我正在尝试验证我的字符串是否与模式匹配。也就是说,完整的字符串可以写成那个模式。但是,如果任何子字符串与该模式匹配,则preg_match
返回。true
(例如preg_match("#[a-z]*#, "333k")
返回1
,我不想这样做。在这个例子中,我宁愿验证,整个字符串只包含小的拉丁字母。)
3 回答
在正则表达式模式中,您可以分别使用开始和结束标记来指示字符串的开始和结束。这样,您可以使表达式仅匹配整个字符串,而不是任何类型的子字符串。在您的情况下,它将如下所示:^
$
preg_match("#^[a-z]*$#", "333k");
您还可以使用这些标记之一指定模式必须只匹配字符串的开头或结尾。
请注意,$
锚点还在字符串末尾的换行符字符序列之前匹配(是的,即使m
未指定 MULTILINE 标志)。看到这些测试,都返回一个匹配:
if (preg_match("#^[a-z]*$#", "ok")) echo "OK!\n"; // => is OK!
if (preg_match("#^[a-z]*$#", "ok\n")) echo "OK!\n"; // => is OK!
if (preg_match("#(*ANY)^[a-z]*$#", "ok\r\n")) echo "OK!"; // => is also OK!
$
您可以使用D
修饰符“修复”此行为。符合 PCRE 的PCRE_DOLLAR_ENDONLY
修饰符使锚点$
匹配在字符串的最后(不包括字符串中最后一个换行符之前的位置)。
/^\d+$/D
等于
/^\d+\z/
and 匹配由 1 个或多个数字组成的整个字符串,不会匹配"123\n"
,但会匹配"123"
。
或者,要将字符串匹配锚定在字符串的开头和结尾,您也可以考虑使用\A
和\z
anchors。
preg_match('~\A[a-z]*\z~', "333k");
^^ ^^
\A
和\z
是PHP 正则表达式中字符串锚点的明确开始和结束(因为它们的行为不依赖于任何正则表达式修饰符,即使您指定m
MULTILINE 修饰符,它们也会继续断言字符串开始/结束位置)。在PHP 文档中查看有关 PHP 正则表达式锚点的更多信息。
但请注意\Z
:\Z
将匹配最后一个换行符之前的整个字符串,而\z
只会匹配字符串的最后,即字符串中的所有字符之后(参见Whats the difference between \z and \Z在正则表达式中以及何时以及如何使用它?)
我超级喜欢正则表达式,但不是为了这个任务——这是不必要的开销,因为有一个单一的、直接的、非正则表达式等价物。 https://www.php.net/manual/en/function.ctype-lower.php
代码:(演示)
$tests = [
'Test',
'test',
'test1',
'1test',
'test!'
];
foreach ($tests as $test) {
echo "$test: " , (ctype_lower($test) ? 'true' : 'false') , "\n";
}
输出:
Test: false
test: true
test1: false
1test: false
test!: false
ps 对于记录,返回一个空字符串false
。我不确定您对此测试单元的逻辑验证要求。