【问题标题】:PHP PCRE unicode escape [duplicate]PHP PCRE unicode转义[重复]
【发布时间】:2013-01-19 07:40:00
【问题描述】:

我正在使用一个包含带有“\uXXXX”的表达式的正则表达式数据库,这当然会破坏 PHP PCRE。

那么,两个部分的问题,有没有办法告诉 PCRE 接受这些序列?

我解决了这个问题,幸运的是这只是一个序列,通过这样做:

$regx = str_ireplace('\u00a7', '\xa7', $regx);

但是当我尝试这样做时:

$regx = preg_replace("/\\u(\w+)/i", "\x$1", $regx);

我还在 -

警告:preg_replace() [function.preg-replace]:编译失败:PCRE 不支持偏移量 1 处的 \L、\l、\N{name}、\U 或 \u

它需要双重转义\u => \\\\u,而不仅仅是\\u,为什么/有更好的方法?注意:我实际上只需要做同样的事情,更重要的是,才能在这篇文章中输入正确的字符串。

更新:在我们的服务器上运行 5.3.3

【问题讨论】:

  • 您可以在正则表达式之后添加u 修饰符(即使用您的i 修饰符)以指定表达式为UTF-8 格式。见php.net/manual/en/reference.pcre.pattern.modifiers.php
  • 我确实尝试过,但仍然收到错误。 'u' 修饰符允许我在正则表达式模式中使用 § 而不是序列。您在下面发布的内容似乎是错误仍然发生的原因。

标签: php unicode pcre unicode-escapes


【解决方案1】:
$regx = preg_replace("/\\u(\w+)/i", "\x$1", $regx);

这不起作用的原因是您需要双重转义反斜杠。

目前,\\u 位于 PHP 双引号字符串中,这意味着 PHP 将 \\ 转义为一个斜杠。

这个单斜杠然后被赋予PRCE,所以正则表达式解析器只看到\u。这失败了,因为\u 不是正则表达式中的有效转义序列。

如果您想实际匹配 PHP 正则表达式中的反斜杠字符,您需要实际提供四个反斜杠。

$regx = preg_replace("/\\\\u(\w+)/i", "\x$1", $regx);

是的。它很丑。但就是这样。

从技术上讲,这适用于任何正则表达式反斜杠,所以理论上你的 \w 也应该有一个双反斜杠,但你可以摆脱它,以及大多数其他的,因为 \w 对 PHP 没有意义,所以它不解析它。这是一种有用的行为,但在出现问题时确实会让事情变得更加混乱,就像本例一样。

【讨论】:

  • 所以 php 在评估正则表达式之前试图提供帮助并避开我的反斜杠? double 变成 single 然后遇到无效的转义 ...
  • 嗯,这并不是说它试图提供帮助;这就是事情的运作方式,因为它在字符串中。在将表达式传递给 PCRE 引擎之前,PHP 会按照任何其他字符串处理字符串转义。不幸的是,PHP 字符串和 PCRE 正则表达式都使用反斜杠作为转义字符。如果您在 PHP 字符串中使用 javascript 字符串或使用相同反斜杠转义字符的任何其他内容,您将获得类似的效果。对于需要处理它们的每种语言,斜线都会成倍增加。
【解决方案2】:

\u 不适用于 PHP,但 \x 可以。 PCRE文档的解释:

\x{hhh..} character with hex code hhh.. (non-JavaScript mode)
\uhhhh    character with hex code hhhh (JavaScript mode only)

修饰符 u 不应该被遗忘。 (“Javascript 模式”是一个“内部”标志)

另一种解释 Unicode 序列(\u 为 \U)的解决方案是使用 intl/Transliterator (PHP >= 5.4):

$in = '\u0041\U00000062';
$out = transliterator_create('Hex-Any')->transliterate($in);
var_dump($out); # string(2) "Ab"

【讨论】:

  • 感谢您的提示。不幸的是,我们的服务器上仍在使用 5.3。
猜你喜欢
  • 2021-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-21
  • 1970-01-01
  • 2023-04-09
  • 1970-01-01
相关资源
最近更新 更多