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


preg_match() function in PHP returns improper result

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

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

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

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

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

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

但是,要检查 Unicode 字符串的实际长度,您需要使用 mb_strlen 。有关示例,请参阅我的这篇文章。

请参阅此演示:

$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)

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

<?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ä"
}