【问题标题】:Different regex output on 2 PHP systems?2个PHP系统上的不同正则表达式输出?
【发布时间】:2014-06-08 09:25:48
【问题描述】:

鉴于此测试脚本:

<?php

echo setlocale(LC_ALL, '') . "\n";

$in = 'Città';

$var = preg_replace('/\s+$/', '', $in);

echo bin2hex($in) . "\n";
echo bin2hex($var) . "\n";

Ubuntu 上的 PHP 5.5.3,我得到:

en_GB.UTF-8
43697474c3a0
43697474c3a0

Mac 上的 PHP 5.5.9(通过 Macports)

en_GB.UTF-8
43697474c3a0
43697474c3

Macports 版本是否有任何理由以不同方式对待 à 字符?

我知道 c3a0 在 ASCII 中被视为两个字节时,是 Ã 后跟一个不间断空格。我想知道为什么一个系统将 2 个字节视为 UTF-8 而没有 u 修饰符。

【问题讨论】:

  • 如果您使用/u 修饰符,问题是否仍然存在? php.net/manual/en/reference.pcre.pattern.modifiers.php 模式将是 /\s+$/u
  • @TimJones 使用u 修饰符,php/regex 引擎会将输入视为 UTF-8 字符串。因此,使用u 修饰符它将“识别”0xc3a0à,而没有u 修饰符它将“识别”它们为单独的字符0xc30xa00xa0some kind of space,这就是它删除它的原因,因为 \s 匹配一个空格。
  • @HamZa 是的,这也是我的理解。我很困惑为什么 Ubuntu 系统使用 u 修饰符将0xc3a0 视为一个 unicode 字符而不使用。有什么想法吗?
  • 请检查链接的 libpcre PHP 版本以及使用的配置。我总是建议使用捆绑版本来避免此类问题。可能 PCRE 是用不同的语言环境编译的。
  • 您可以通过简单的测试知道差异是否来自语言环境(用于编译 pcre 模块)。尝试将à\w 匹配。

标签: php regex unicode


【解决方案1】:

使用/umodifier

u (PCRE_UTF8) 此修饰符打开 PCRE 的附加功能 这与 Perl 不兼容。模式字符串被视为 UTF-8。

默认情况下,字符串被视为单字节字符序列;问题是您的某些字符在 UTF-8 中被编码为多字节。虽然0xc3a0 是单个代码点,但\s 将匹配它的第二个字节0xa0,这是一个不间断的空格,因此是空格。

$var = preg_replace('/\s+$/u', '', $in);

应该启用 UTF-8 模式进行匹配,并且应该适用于所有系统。

【讨论】:

  • U+00A0 是不间断空格,而不是换行符(即U+000A),但无论哪种方式,它都是一个空格字符。 +1
  • @AlanMoore:哦,对了——我真傻。谢谢指正。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-03
  • 2010-10-29
  • 2011-01-03
  • 2011-04-02
  • 1970-01-01
  • 1970-01-01
  • 2017-12-30
相关资源
最近更新 更多