PHP中的preg_match()函数返回不正确的结果

时间:2015-11-18 11:08:36

标签: php regex

$sRangeRegex = '/^(.{0,30})?$/';
$value='12345678901234567890123456789ä';
if (!preg_match($sRangeRegex, $value)) {
    alert('not match');
}

当我运行此代码时,它返回' not match'警报信息。但实际上它不应该。 因为实际值的长度应为30($ value中的字符数) 但它显示31 这些变音字符在匹配时会产生问题。 所以我想要解决方案来解决这个问题并且仅使用正则表达式。 感谢。

2 个答案:

答案 0 :(得分:3)

这里已经是常识,为了使用Unicode字符串,PHP正则表达式引擎应该得到一个带有/u标志的模式。一个鲜为人知的事实是,为了匹配Unicode字形,需要使用\X速记类(符合PCRE)。

因此,要对Unicode字符串模式应用一些长度限制,请使用\X而不是.

$pattern = '/^\X{0,30}$/u';

请注意,此正则表达式将匹配包含0到30个Unicode字形的字符串。您不需要任何(...)?个可选模式,因为限制量词中的0已经完成此任务。

但是,要检查Unicode字符串的实际长度,您需要使用mb_strlen。有关示例,请参阅this post of mine

请参阅this demo

$pattern = '/^.{0,30}$/u';
$value='12345678901234567890123456789Å';
if (!preg_match($pattern, $value)) {
    echo "not match\n";
}
else echo "match!\n";

$pattern = '/^\X{0,30}$/u';
$value='12345678901234567890123456789Å';
if (!preg_match($pattern, $value)) {
    echo 'not match';
}
else echo "match!";

结果:

not match (this is the regex with a dot)
match!    (the regex based on \X)

答案 1 :(得分:0)

你需要告诉你的正则表达式引擎它应该在utf模式下使用u标志作为修饰符:

<?php
$pattern = '/^(.{0,30})?$/u';
$subject='12345678901234567890123456789ä';

if (!preg_match($pattern, $subject, $tokens)) {
    alert('not match');
}
var_dump($tokens);

请注意模式定义中的尾随u

输出结果为:

array(2) {
  [0] =>
  string(31) "12345678901234567890123456789ä"
  [1] =>
  string(31) "12345678901234567890123456789ä"
}