PHP中的字符占3位

我在字符串(字符数组)中遇到问题,因为一个字符占据3个位置,这使我的代码产生了意外的结果

检查此代码:

<?php
$input1="t’n";
for($i=0;$i<strlen($input1);$i++){
    echo $input1[$i] .'<br/>';
}
echo '<br>'.'=================='.'<br>';
$input2='test';
for($i=0;$i<strlen($input2);$i++){
    echo $input2[$i] .'<br/>';
}
echo '<br>'.'Strange ===> ';
echo $input1[1].$input1[2].$input1[3];

查看照片:

PHP中的字符占3位

我们注意到这个字符’在将字符串作为字符数组处理时占据3个位置,并且三个字符必须保持在一起才能构成正确的字符。

当我编写的代码使输入的字符串反向包含此字符时,我会遇到这种情况 例如t’n => n’t 有什么建议吗?

预先感谢

dtzel 回答:PHP中的字符占3位

如您所见,只要字符串包含多字节字符,就不能像使用数组那样使用字符串。没关系,我们将使用mb_ *函数提取每个字符:

$input = 't’n';
$result = [];

for ($i=0,$max=mb_strlen($input); $i < $max; $i++) {
    $result[] = mb_substr($input,$i,1); 
}

echo implode('<br>',$result);

好的,看起来不错,您可以使用array_reverse轻松获得反向字符串:

echo implode('',array_reverse($result));

但这不是那么简单。让我们考虑一个包含字符的字符串:

$input = "a\xcc\x80e"; // àe

此字符串具有三个代码点:

  • U + 0061拉丁文小写字母A(\ x61)
  • U + 0300合并重音符(\ xcc \ x80)
  • U + 0065拉丁文小写字母E(\ x65)

问题:如果我们使用前面的代码来反转此字符串,则会以相反的顺序获得三个代码点,因此字符串"e\xcc\x80a" // èa。请注意,重音现在位于 e 上,而不再位于 a 上。

要获得预期结果"ea\xcc\x80"),我们必须使用字节而不是字节,代码点,而应使用字素。 (一个字素包括字符和最终的字符)。

为此,我们可以使用grapheme_* functions代替mb_*函数,方法完全相同:

for ($i=0,$max=grapheme_strlen($input); $i < $max; $i++) {
    $result[] = grapheme_substr($input,1); 
}

其他可能性,我们可以使用与字素匹配的\X pcre功能:

if ( preg_match_all('~\X~u',$input,$matches) ) {
    $result = $matches[0];
}

Nota Bene:您显然可以避免创建一个数组来反转字符串:

function grapheme_strrev($input) {
    $result = '';
    for ($i = grapheme_strlen($input) - 1; $i > -1; $i--) {
        $result .= grapheme_substr($input,1);
    }
    return $result;
}
,

该字符为U + 2019右单引号(数字为十六进制)。在UTF-8中,它的编码为e2 8099。因此,当您反转74 e2 80 99 6e时,您需要制作6e e2 80 99 74。

您可以按以下字节字符串处理此问题:

  • 将$ i从$ input的结尾迭代到开头。
  • 如果$ input [$ i]在0到127之间(含0和127),请将其复制到$ output的末尾。
  • 如果$ input [$ i]在128到191之间(如果对char进行了签名,则在-128到-65之间),请保留它。
  • 如果$ input [$ i]在192和255之间(-64和-1),请将其和保留的字节作为一个块复制到$ output的末尾。

所有以UTF-8编码的Unicode字符要么是一个7位字符(高字节清零),要么是一个多字节序列,其中第一个字节从11开始,其余所有字节从10开始。

UTF-8中存在无效的字节序列(例如,您将永远看不到fe和ff字节);您如何处理它们取决于您。

,

这不起作用,我现在没有时间做更多的事情。但是您应该能够使用几个函数来检测字符编码,并在必要时进行转换。我以某种方式怀疑这是您运动的目标,但是...看起来似乎非常昂贵(计算上)。无论哪种方式,都可以在手册中搜索编码功能,然后执行类似以下的操作-您将能够处理每个字符。无论出于何种原因,我都无法在CLI中成功调用convert函数。

<?php
$input1="t’n";
$ce = mb_internal_encoding(); //current encoding in use by php/this script by X configuration
for($i=0;$i<strlen($input1);$i++){
    if(mb_detect_encoding($input1[$i],"auto",true) == $ce){
        echo $input1[$i] .'<br/>';
    }
    else{
        echo mb_convert_encoding($input1[$i],$ce,"auto");
    }
}
echo '<br/>'.'=================='.'<br/>';
$input2='test';
for($i=0;$i<strlen($input2);$i++){
    echo $input2[$i] .'<br/>';
}

抱歉,不完整,希望对您有所帮助,或者比我自己更精通的人可以加入...

本文链接:https://www.f2er.com/3034453.html

大家都在问