Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在PHP中解析多字节字符串_Php_String_Parsing_Multibyte - Fatal编程技术网

在PHP中解析多字节字符串

在PHP中解析多字节字符串,php,string,parsing,multibyte,Php,String,Parsing,Multibyte,我想写一个基于状态机的(HTML)解析器,但我怀疑如何正确读取/使用输入。我决定将整个输入加载到一个字符串中,然后像处理数组一样处理它,并将其索引保持为当前解析位置 单字节编码不会有问题,但在多字节编码中,每个值并不代表一个字符,而是代表一个字符的一个字节 示例: $mb_string = 'žščř'; //4 multi-byte characters in UTF-8 for($i=0; $i < 4; $i++) { echo $mb_string[$i], PHP_EOL

我想写一个基于状态机的(HTML)解析器,但我怀疑如何正确读取/使用输入。我决定将整个输入加载到一个字符串中,然后像处理数组一样处理它,并将其索引保持为当前解析位置

单字节编码不会有问题,但在多字节编码中,每个值并不代表一个字符,而是代表一个字符的一个字节

示例:

$mb_string = 'žščř'; //4 multi-byte characters in UTF-8

for($i=0; $i < 4; $i++)
{
   echo $mb_string[$i], PHP_EOL;
}
Ĺ
ž
Ĺ
Ą

这意味着我不能迭代循环中的字符串来检查单个字符,因为我不知道是否在字符的中间。< /P> 因此,问题是:

  • 如何安全读取多字节数据 字符串中的单个字符 性能友好的方式
  • 和你的朋友一起工作是个好主意吗 字符串,因为它是此 案子
  • 您将如何读取输入
    • 就是你要找的东西

      • 只需要一个接一个的mb_substr字符
      • 直到PHP6
      • 到底是什么输入?通常的方式
      mb_内部编码(“UTF-8”);
      $mb_string='闑闗ř';
      $l=mb_字符串($mb_字符串);
      
      对于($i=0;$i而不使用mdb_related函数和多字节编码字符串,您可以使用标准子字符串函数,该函数读取用于编码的字节的倍数

      例如,对于UTF-8编码(2字节)字符串,如果需要字符串中的第一个字符

      $string = 'žščř'; //4 multi-byte characters in UTF-8
      
      您必须获得$string[0]和$string[1]值,因此实际上您正在寻找索引0和1之间的子字符串(第一个字符)

      请注意,$string[0]或$string[N]将引用多字节字符串的第一个字节(或第N个字节)


      关于,

      请注意,
      mb_split
      的注释部分包含了许多如何将多字节字符串分解为字符数组的示例-例如,@Dav我认为他并不真的需要数组。输入指的是要解析的HTML代码。可能有完全不同的方法将字符串与状态机w一起使用我错过了:-)。。。但是mb_substr看起来不错(如果我知道字符串编码,这不是很明显)@Dav谢谢,我正在考虑将字符串转换为字符数组,但我认为这不是最干净的解决方案之一。我会觉得很脏:-)这里的问题是
      mb\u substr
      是(我猜)
      O(n)
      所以每个字符调用
      mb\u substr
      一次将是
      O(n^2)
      。如果您可能要处理非常大的字符串,那么这将变成一个性能问题。不幸的是,我认为目前没有更好的选择;也有黑客,但他们只适用于UTF-8。理想的解决方案是
      O(n)
      ,适用于mbstring支持的所有编码;不幸的是,如果不修补mbstring,我认为这样的解决方案实际上是不可能的。要知道我必须读取多少字节并不难?这是一个简单的示例,但一般来说,我不知道输入上有哪些字符(UTF-8字符可以是1-4字节长)。是的,您必须确定使用了多少字节,但这是一个答案,它可能会为您提供一些有关使用非mb_相关函数以及操作多字节字符串的信息。希望您觉得它有用。这个答案有误导性,因为它表明所有UTF-8字符都是2字节长的。实际上,字节长度取决于所表示的字符。正如@PetrPeller在上面的评论中所指出的,UTF-8字符可以占用1个字节,也可以占用4个字节。
      $string = 'žščř'; //4 multi-byte characters in UTF-8