1

我有这个代码:

$reg = "^[a-zA-ZáčďéíľňóřťšúůýžÁČĎÉÍĽŇÓŘŤŠÚŮÝŽ]{3,20}$"; // At least 3

$string = "šš"; // Only 2 letters

echo preg_match("+".$reg."+", $string);

'š' 是捷克共和国的特殊字母。

它与 1 相呼应。为什么?这是PHP的错误吗?

4

3 回答 3

2

使用u修饰符。这将形成一个PCRE_UTF8兼容的匹配。

echo preg_match("+" . $pattern . "+u", $string);

这将返回0两个字符串,但如果有 3 个字符,则返回 1。

文档没有解释原因,我在 PCRE_UTF8 上找不到任何简单解释的东西。如果我不得不冒险猜测,那将是{}默认情况下适用于字节,但u启用了字符。

于 2013-11-13T14:59:59.230 回答
1

查看手册,尤其是函数签名:

int preg_match ( string $pattern , string $subject [, array &$matches [, int $flags = 0 [, int $offset = 0 ]]] )

它返回一个 int,0 表示未找到匹配项,1 表示找到匹配项。如果您想要将这些匹配项分配给变量,则必须传递第三个参数:

if (preg_match($pattern, $string, $matches))
{//if it returns 1, preg_match is true
    var_dump($matches);
}

再加上您匹配的是非 ASCII 字符,也有一个特殊的手册页,您可能会发现它匹配 2 个字符,而不是 3 个。所以你必须求助于那些特殊字符的unicode。š例如,m 与 匹配/\u0160/
有关 regex + unicode 的更多信息可以在这里获得
Unicode 字符“更宽”(它们占用更多字节),但是有一个 utf8 兼容的修饰符u::

var_dump(preg_match('+'. $pattern . '+u', $string, $matches));
var_dump($matches);

话虽如此:我环顾四周,因为 PCRE 提供脚本名称来匹配整个 unicode 字母表。快速浏览一下 wiki,以及其他一些来源告诉我,也许:

/\p{Cyrillic}/

可能有效,但西里尔字母并不完全相同,无论如何,在本页底部,您可以找到一个包含捷克字母表的所有 unicode 代码的表格。

你不能为此责怪 PHP ;-) 顺便说一句,把
一个模式串在一起很好,但是有一个更安全的方法:使用preg_quote函数

string preg_quote ( string $str [, string $delimiter = NULL ] )

在你的情况下:

$pattern = preg_quote($reg, '+');
于 2013-11-13T14:56:08.063 回答
0

这取决于特殊字符的编码方式。如果您的 php 文件以单字节编码存储,它应该可以工作,但如果您使用的是 utf-8,则不能。如果您的 php 文件是 utf-8,则特殊字符实际上是几个字节。它们中的每一个都是要在字符类中匹配的有效字节。这同样适用于 $string 它。尝试:

var_dump(strlen("šš")); // should output int(4) 

修饰符u激活 PCRE 模式的 unicode/utf-8 模式并改变行为。

$reg = "^[a-zA-ZáčďéíľňóřťšúůýžÁČĎÉÍĽŇÓŘŤŠÚŮÝŽ]{3,20}$";
$string = "šš";    
echo preg_match("(".$reg.")u", $string);

这也允许一些其他功能。

$reg = "(^\\pL{3,20}$)u"; 
var_dump(preg_match($reg, "šš"));
var_dump(preg_match($reg, "šššš"));

\pL是 unicode 字符属性“字母”的缩写。您可以查看PHP 手册以获取更多可能性。

于 2013-11-13T15:16:39.777 回答