【问题标题】:PHP correct regex expression doesn't work in PHP 5.3.3-7 with unicodePHP 正确的正则表达式在带有 unicode 的 PHP 5.3.3-7 中不起作用
【发布时间】:2014-08-04 19:07:48
【问题描述】:

我正在尝试让这个正则表达式工作,它旨在在一个句子中找到两个单词。

echo (int)preg_match('/\bHello\W+(?:\w+\W+){0,6}?World\b/ui', 'Hello, world!', $matches).PHP_EOL;
print_r($matches);

而且效果很好:

1
Array
(
    [0] => Hello, world
)

...但仅限于拉丁词。如果我切换到 unicode,它什么也找不到。也无需查看语法,因为它来自a book(第 8 章“查找彼此靠近的两个单词”)。问题是它只适用于拉丁词,但不适用于像这样的 unicode 字符串:'Привіт, світу!' (乌克兰语)。

我检查了几乎所有可能的问题:

✓ 我在正则表达式模式中使用了 'u' 标志。

✓ 在执行此语句之前,我在代码中启用了 UTF-8 支持,如下所示:

 ini_set('default_charset', 'UTF-8');
 mb_internal_encoding('UTF-8');
 mb_regex_encoding('UTF-8');

✓ 我在 Debian Linux 上的 PCRE 编译正确:

 # pcretest -C
 PCRE version 8.02 2010-03-19
 Compiled with
   UTF-8 support
   Unicode properties support
   Newline sequence is LF
   \R matches all Unicode newlines
   Internal link size = 2
   POSIX malloc threshold = 10
   Default match limit = 10000000
   Default recursion depth limit = 10000000
   Match recursion uses stack

✓ 我什至尝试在此处将这个奇怪的序列 (*UTF8) 添加到模式 according to this answer 中,但没有帮助:

echo (int)preg_match('/(*UTF8)\bПривіт\W+(?:\w+\W+){0,6}?світу\b/ui', 'Привіт, світу!', $matches).PHP_EOL;
print_r($matches);

结果:

0
Array
(
)

所以我的问题是:为什么 unicode 在我在同一代码中使用的其他 unicode 模式完美地工作时不能在这里工作?不过它们更简单一些,就像这样:

echo (int)preg_match('/Привіт/ui', 'Привіт, світу!', $matches).PHP_EOL;
print_r($matches);

这出人意料地有效:

1
Array
(
    [0] => Привіт
)

最后很有趣,它在 online regex tester 上完全可以正常工作(这就是为什么我实际上如此沮丧,我测试了它,然后希望在我的代码中也可以工作,但它没有)。

哦,聪明的 Stackoverflow,请给他一个提示。

【问题讨论】:

  • 这可能太明显了,但是您的文件保存为utf8吗?
  • 能否说明您的 PHP 版本和操作系统?
  • 在我的 Windows 系统上,您的 REGEX 按预期运行。在 unbuntu 机器上,它会生成以下警告:“PHP 警告:preg_match():编译失败:(*VERB) 在偏移量 5 处无法识别”。您是否已将错误级别设置为警告?
  • 我有以下代码:ini_set("display_errors", "on");错误报告(E_ALL);并且脚本在运行时和日志中都不会产生任何错误:(

标签: php regex unicode utf-8 pcre


【解决方案1】:

我曾经遇到过类似的问题,发现模式中的 UTF-8 符号不适用于某些版本的 PHP。即使是当时的 5.3 版本也有这个问题。在此处查看您的示例:http://3v4l.org/7HurJ。根据该测试,您必须至少拥有 5.3.4 才能使该模式正常工作,但我认为,版本号在这里并没有多大意义。也许,它实际上取决于一些编译选项,或者可能有一种解决方法,但我没有深入挖掘,只是简单地调整了我的方法,不在表达式中使用任何“有趣”的符号。

【讨论】:

  • 非常感谢您,也感谢您提供这个出色的工具。这确实是与 php 版本相关的问题。我使用的 VPS 有点旧(Debian 6,512 MB RAM,几年前订购但仍然有用)。我在本地 Debian 机器上尝试了 PHP 5.6.0beta3,它看起来完美无瑕。再次对给您带来的麻烦表示歉意并感谢您的帮助。这是解决方案,更新PHP版本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-04
  • 2013-06-19
  • 1970-01-01
  • 2018-09-08
  • 1970-01-01
相关资源
最近更新 更多