php - 如何使用 u 标志匹配日语正则表达式?

3

当我输入以下字符串时,preg_match 函数出现了奇怪的情况。我使用 'u' 标志是因为我要匹配一个混合的日语字符串。

<?php
 $subject="/hello/カメラ/";
 $pattern='#^/hello/([\p{Han}\p{Katakana}\p{Hiragana}\w\-]+)/#u';
 $result=preg_match($pattern,$subject);
 echo $result; // 1

 $subject="/hello/カレンダー/";
 $pattern='#^/hello/([\p{Han}\p{Katakana}\p{Hiragana}\w\-]+)/#u';
 $result=preg_match($pattern,$subject);
 echo $result; // 0
?>

请注意,两个$pattern变量都具有相同的构造'/hello/katakana/'。那么,为什么第一个$result是1而第二个是0呢?
这是一个bug吗?
更新: 我在Mac上运行PHP版本5.5.24。

你正在运行哪个版本的PHP?我刚刚在我的电脑上测试了你的代码,使用的是5.5.9版本,两个结果都是1。 - David Vartanian
2
必须运行旧版本的PHP,https://3v4l.org/frX5U。 - chris85
@DavidVartanian 我在 Mac 上运行 PHP 版本 5.5.24。所以,这终究是一个 bug 啊,是吧。 - dev4life
1
是的可能。也许这个链接可以帮助你:http://php.net/manual/en/function.preg-match.php#94424。你看到了吗? - David Vartanian
@DavidVartanian 不是的。我刚刚看了一下。我更新了正则表达式以使用范围,现在它可以工作了! - dev4life
2个回答

1

感谢David Vartanian的帮助。

为了使正则表达式适用于两种情况,我不得不按照以下方式更新模式。

$pattern='#^/hello/([\x{30A0}-\x{30FF}\x{3040}-\x{309F}\x{4E00}-\x{9FBF}\w\-]+)/#u';

然而,正如chris所提到的那样,旧的模式在PHP 5.5.9及更高版本上似乎可以使用。

我建议您更新您的PHP。较新版本的PHP带有许多错误修复和库的更新(在这种情况下,是正则表达式引擎PCRE)。 - nhahtdh

0
你可以使用mb_ereg_match(),这个函数专门用于多字节正则表达式,不要与已弃用的ereg_*混淆。只需删除定界符和修饰符u即可使用它。
<?php

$subject="/hello/カメラ/";
$pattern='^/hello/([\p{Han}\p{Katakana}\p{Hiragana}\w\-]+)/';
$result =  mb_ereg_match($pattern, $subject);

echo "<pre>";
print_r($result);

$subject="/hello/カレンダー/";
$pattern='^/hello/([\p{Han}\p{Katakana}\p{Hiragana}\w\-]+)/';
$result =  mb_ereg_match($pattern, $subject);

print_r($result);

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