【问题标题】:UTF-8 in PHP regular expressions [duplicate]PHP正则表达式中的UTF-8 [重复]
【发布时间】:2011-09-18 11:25:21
【问题描述】:

我需要正则表达式方面的帮助。我的字符串包含 unicode 字符,下面的代码不起作用。

前四个字符必须是数字,然后是逗号,然后是任何字母字符或空格... 我已经读到如果我在正则表达式末尾添加 /u 但它对我不起作用......

我的代码适用于非 unicode 字符

$post = '9999,škofja loka';;
echo preg_match('/^[0-9]{4},[\s]*[a-zA-Z]+', $post);

感谢您的回答!

【问题讨论】:

    标签: php regex utf-8


    【解决方案1】:

    更新答案:
    现在已经过测试并且可以正常工作了

    $post = '9999, škofja loka';
    echo preg_match('/^\\d{4},[\\s\\p{L}]+$/u', $post);
    

    \\w 不起作用,因为它不包含所有 unicode 字母,并且除了字母之外还包含 [0-9_]。

    同样重要的是u修饰符激活unicode模式。

    如果逗号后面可以有字母或空格,那么你应该把它们放在同一个字符类中,在你的正则表达式中,逗号后面有0个或多个空格,然后只有字母。

    请参阅http://www.regular-expressions.info/php.html 了解 php 正则表达式的详细信息

    \\p{L}(Unicode 字母)解释为here

    重要的是使用字符串结束边界$ 来确保确实验证了完整的字符串,否则它将仅匹配第一个空格并忽略其余部分。

    【讨论】:

    • 不起作用 = 返回 0: $post = '9999,škofja loka'; echo preg_match('/^[0-9]{4},[\s\w]+/u', $post);
    • @gašper,所以现在我测试了它online,似乎PHP需要双重转义preg_match('/^\\d{4},[\\s\\w]+$/u', $post);但似乎\\w不包括unicode字符,即使@987654333 @修饰符。
    • @gašper,我做了更多测试并更新了我的答案
    • @stema,这项工作非常好,谢谢!
    • js 中有一个 unicode 库等等xregexp.com
    【解决方案2】:

    [a-zA-Z] 将仅匹配 a-z 和 A-Z 范围内的字母。您有非 US-ASCII 字母,因此无论 /u 修饰符如何,您的正则表达式都不会匹配。您需要使用单词字符转义序列(\w)。

    $post = '9999,škofja loka';
    echo preg_match('/^[0-9]{4},[\s]*[\w]+/u', $post);
    

    【讨论】:

    • 在我的情况下不适用于您的代码
    • 注意:\w 也会匹配数字,\s 不需要方括号。简洁:/^\d{4},\s*\w+/u
    • 你测试了吗,还是不行
    • 即使在 UTF-8 模式下,\w 也只能匹配 [A-Za-z0-9_]。您必须使用特定于 Unicode 的结构,例如 \p{L} 以及 /u 标志。
    • @Alan:区域设置会影响什么是字母,什么不是。对我来说,我发布的正则表达式有效(fi_FI.UTF-8 语言环境)。
    【解决方案3】:

    问题是你的正则表达式。您明确表示您只会接受a b c ... z A B C ... Z。 š 不在 a-z 集中。请记住,š 与 s 和其他字符一样不同。

    因此,如果您真的只想要一个字母序列,那么您需要测试 unicode 属性。例如

    echo preg_match('/^[0-9]{4},[\s]*\p{L}+', $post);
    

    这应该有效,因为 \p{L} 匹配任何被视为字母的 unicode 字符。不只是 A 到 Z。

    【讨论】:

    • 这不起作用:这应该返回 0 但它返回 1 $post = '9999,ščćžđkofja loka,.(?*'; echo preg_match('/^[0-9]{ 4},[\s]*\p{L}+/', $post);
    • 一件事 - 在您的测试程序中是 UTF-8 格式的 $post 程序?抱歉,我不擅长 php。但是在 perl 中,如果你只输入字符 š,你会得到一个 9A 字节的字符串。在 UTF-8 中,该字符需要是两个字节 C5 A1(在拉丁字符编码中看起来像 Å¡。
    【解决方案4】:

    添加u,并记住尾部斜杠:

    echo preg_match('/^[0-9]{4},[\s]*[a-zA-Z]+/u', $post);
    

    已编辑:

    echo preg_match('/^\d{4},(?:\s|\w)+/u', $post);
    

    【讨论】:

    • 仅u 修饰符是不够的,参见。 @jmz 的回答。
    • @jensgram: \w 加上 u 修饰符也不够;参看。 @stema 的回答。 ;)
    • @alan Bah...我想我以后会跳过星期一早上...
    猜你喜欢
    • 2016-07-25
    • 1970-01-01
    • 2019-02-27
    • 1970-01-01
    • 2011-01-04
    • 2013-02-24
    • 2013-12-01
    • 1970-01-01
    相关资源
    最近更新 更多