PHP正则表达式中的UTF-8

17

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

前四个字符必须是数字,然后是逗号,然后是任何字母字符或空白字符... 我已经阅读了如果在正则表达式末尾添加/u,但对我没有用...

我的代码可以处理非unicode字符

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

感谢你的回答!

4个回答

35

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

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

\\w无法使用,因为它不包括所有Unicode字母,并且除了字母外还包括[0-9_]

重要的是使用u修饰符来启用Unicode模式。

如果逗号后面可以是字母或者空格,则应将它们放入同一字符类中。在您的正则表达式中,逗号后有0个或多个空格,然后仅有字母。

有关PHP正则表达式详细信息,请参见http://www.regular-expressions.info/php.html

\\p{L}(Unicode字母)的说明在此处

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


不起作用 = 返回0:$post ='9999,škofja loka';echo preg_match('/^[0-9]{4},[\s\w]+/u', $post); - Gasper
@gašper,现在我已经在在线网站上测试了它,似乎PHP需要双重转义preg_match('/^\\d{4},[\\s\\w]+$/u', $post);但是似乎\\w不包括Unicode字符,即使使用了u修饰符。 - stema
1
@gašper,我进行了更多的测试并更新了我的答案。 - stema
我可以在JS中使用那个正则表达式吗? - Gasper
@gašper,我不这么认为,http://www.regular-expressions.info/javascript.html 解释了 JavaScript 正则表达式的风格,并且它说它不支持 Unicode(除非你明确地给出字符,比如 ^\d{4},[\sa-zA-Zš]+$)。 - stema
1
有一个JS Unicode库,而且还有更多的功能:http://xregexp.com/ - llamerr

8

[a-zA-Z] 只匹配 a-z 和 A-Z 的字母。你有非美国ASCII字母,因此你的正则表达式不会匹配,无论是否使用 /u 修饰符。你需要使用单词字符转义序列 (\w)。

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

你的代码在我的情况下无法工作。 - Gasper
注意:\w也会匹配数字,而\s不需要方括号。简洁地说:/^\d{4},\s*\w+/u - searlea
你测试过了吗?还是不起作用。 - Gasper
6
即使在UTF-8模式下,\w只匹配[A-Za-z0-9_]。你需要使用Unicode特定的构造,如\p{L}以及 /u标志。 - Alan Moore
1
@Alan:Locale 会影响什么是字母,什么不是。对我来说,我发布的正则表达式有效(fi_FI.UTF-8 locale)。 - jmz

7
问题出在你的正则表达式上。你明确表示只接受 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); - Gasper
有一件事 - 在你的测试程序中,$post程序是否采用UTF-8编码?抱歉我不太擅长php。但是在perl中,如果您只输入字符š,则会得到一个由一个字节9A组成的字符串。在UTF-8中,该字符需要两个字节C5 A1(在拉丁字符编码中看起来像Å¡)。 - Sodved

0

添加一个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
@jensgram:仅使用u修饰符的\w也不够;请参考@stema的回答。;) - Alan Moore
@alan 巴啦啦小魔仙... 我想我以后会跳过星期一早上了... - searlea

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接