Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP的错误?特殊字母错误_Php_Regex - Fatal编程技术网

PHP的错误?特殊字母错误

PHP的错误?特殊字母错误,php,regex,Php,Regex,我有以下代码: $reg = "^[a-zA-ZáčďéíľňóřťšúůýžÁČĎÉÍĽŇÓŘŤŠÚŮÝŽ]{3,20}$"; // At least 3 $string = "šš"; // Only 2 letters echo preg_match("+".$reg."+", $string); š是捷克共和国的特殊字母 它呼应着1。为什么? 这是PHP的错误吗?请查看,尤其是函数签名: int preg_match ( string $pattern , string $subj

我有以下代码:

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

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

echo preg_match("+".$reg."+", $string);
š是捷克共和国的特殊字母

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

请查看,尤其是函数签名:

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个。因此,你必须求助于独角兽来寻找那些特殊的角色<例如,代码>š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;-)
顺便说一句,把一个图案串在一起是很好的,但有一个更安全的方法:

就你而言:

$pattern = preg_quote($reg, '+');
使用。这将使PCRE\U UTF8兼容匹配

echo preg_match("+" . $pattern . "+u", $string);
这将为两个字符串返回
0
,但如果有3个字符,则返回1


文档没有解释原因,我在PCRE_UTF8上也找不到任何简单的解释。如果我不得不大胆猜测,
{}
默认应用于字节,但启用了
u
的字符。

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

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字符属性“letter”的缩写。您可以在中查找更多的可能性。

如果您正在搜索非ascii字符,则需要在正则表达式模式中包含
u
修饰符。@wumm:+非常好:@Reeno,看起来确实是一个奇怪的选择,使用+作为分隔符是否意味着您不能在正则表达式中使用+?@OGHaza true。但奇怪并不意味着这是错的@奥加扎:你可以逃脱它。但是如果使用/作为分隔符,则必须在regexp中转义/。。。如果您的regexp中不需要+,为什么不使用它作为分隔符呢?它应该返回0,因为当他通过时,他正在搜索至少3个字符2@STTLCU:没错,我已经添加了unicode文档的链接,我正在检查捷克字母表是否有脚本名。。。似乎没有,尽管这可能是因为Unicode字符使用的字节数(即可变宽度编码)。
$reg = "(^\\pL{3,20}$)u"; 
var_dump(preg_match($reg, "šš"));
var_dump(preg_match($reg, "šššš"));