【发布时间】:2013-04-28 20:34:33
【问题描述】:
我正在尝试验证我的字符串是否与模式匹配。也就是说,完整的字符串可以写成那个模式。
但是preg_match 返回true,如果任何子字符串匹配该模式。
(例如preg_match("#[a-z]*#, "333k") 返回1,我不想这样做。
在这个例子中,我宁愿验证,整个字符串只包含小的拉丁字母。)
【问题讨论】:
标签: php regex string validation preg-match
我正在尝试验证我的字符串是否与模式匹配。也就是说,完整的字符串可以写成那个模式。
但是preg_match 返回true,如果任何子字符串匹配该模式。
(例如preg_match("#[a-z]*#, "333k") 返回1,我不想这样做。
在这个例子中,我宁愿验证,整个字符串只包含小的拉丁字母。)
【问题讨论】:
标签: php regex string validation preg-match
我超级喜欢正则表达式,但不是为了这个任务——这是不必要的开销,因为有一个单一的、直接的、非正则表达式等价物。 https://www.php.net/manual/en/function.ctype-lower.php
代码:(Demo)
$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
附言作为记录,一个空字符串返回false。我不确定您对此测试单元的逻辑验证要求。
【讨论】:
请注意,$ 锚也匹配位于字符串末尾的换行符序列之前(是的,即使未指定 m MULTILINE 标志)。见these tests, all returning a match:
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/
并匹配由 1 个或多个数字组成的整个字符串,不会匹配 "123\n",但会匹配 "123"。
或者,要将字符串匹配锚定在字符串的 very 开头和结尾,您也可以考虑使用 \A 和 \z 锚点。
preg_match('~\A[a-z]*\z~', "333k");
^^ ^^
\A 和 \z 是 PHP 正则表达式中字符串锚点的明确开始和结束(因为它们的行为不依赖于任何正则表达式修饰符,即使您指定了 m MULTILINE修饰符,他们将继续断言字符串开始/结束位置)。在PHP documentation 中查看有关 PHP 正则表达式锚点的更多信息。
但请注意\Z:\Z 将匹配最后一个换行符之前的整个字符串,而 \z 将仅匹配字符串的最后,即之后字符串中的所有字符(参见Whats the difference between \z and \Z in a regular expression and when and how do I use it?)
【讨论】:
您使用 start 和 end 标记,^ 和 $ 分别表示正则表达式模式中字符串的开始和结束。这样,您可以使表达式仅匹配整个字符串,而不是任何类型的子字符串。在你的情况下,它看起来像这样:
preg_match("#^[a-z]*$#", "333k");
您还可以使用这些标记之一指定模式必须只匹配字符串的开头或结尾。
【讨论】: