【问题标题】:Same encoding (UTF-8), but different lengths of string and content (PHP)相同的编码 (UTF-8),但不同长度的字符串和内容 (PHP)
【发布时间】:2017-06-16 07:19:38
【问题描述】:

我有两个字符串变量 - 第一个变量是在代码中手动设置的 ($date1="14 июня"),第二个变量是使用 cURL 和 phpQuery 从远程页面解析的。 如果我们打印两个变量,结果看起来一样,但长度和内容不同:

echo $date1; //output: 14 июня
echo $date2; //output: 14 июня
echo $date1[2]; //output is space - third symbol in string
echo $date2[2]; //output is � - it's a part of third symbol in string
echo strlen($date1); //output: 7
echo strlen($date2); //output: 12
echo mb_detect_encoding($date1) //output: UTF-8
echo mb_detect_encoding($date2) //output: UTF-8

我想知道是否有解决方案如何将$date2 转换为$date1 的格式/编码?

p.s:有关于 iconv() 的 SO 主题,但我无法找到可行的解决方案。

【问题讨论】:

  • 那里还有不可见的字符。两者都显示echo bin2hex($s)
  • var_dump(array_shift(unpack('H*', $dateX)));这样的表达式转储变量
  • 3134204a756e6514 June313420d0b8d18ed0bdd18f14 июня
  • 那么,你不能比较它们,看看后者有额外的c2a0 字节,而前者使用20 作为空格?
  • 这只是一种不同类型的空间。这取决于你用它做什么。 fileformat.info/info/unicode/char/00a0/index.htm

标签: php encoding utf-8 multibyte


【解决方案1】:

所以你有 2 个字符串:

313420d0b8d18ed0bdd18f - 这使用0x20 字符作为空格。

3134c2a0d0b8d18ed0bdd18f - 这使用 0xC2A0 字节序列作为空格(它是 Unicode 的不间断空格)。

除了这些空格之外,字符串是相同的。

要将类似空格的 unicode 字符替换为正则空格,您可以使用以下正则表达式:

preg_replace('~\p{Zs}~u', ' ', $str)

参考资料:

【讨论】:

  • 有没有任何 php 方法可以像这样转换所有符号/序列/字符?对于空格字符 - 好的,我会替换它,但是其他类似的字符呢?
  • 谢谢@zerkms!现在像explode(' ',$date2) 这样的功能可以正常工作。但长度仍然不同,我认为这是因为西里尔符号。有什么方法可以转换date2,我认为“июня”的长度必须是4。
  • @deeplay 使用mb_strlen() 测量多字节字符串的长度。 echo mb_strlen('июня', 'utf8'); // 4
  • 我知道mb 函数。看起来没有办法转换。对我来说很奇怪,这两个字符串都是 UTF-8 编码,但内容不同。感谢您的帮助。
  • @deeplay июня 以 utf-8 编码时为 8 个字节,因为西里尔字符都是 2 个字节长。而strlen 只是以字节为单位计算字符串的长度。所以不可能说 июня 是 utf8 并且长度不超过 8 个字节。
猜你喜欢
  • 1970-01-01
  • 2012-12-23
  • 1970-01-01
  • 1970-01-01
  • 2018-01-16
  • 2016-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多