我想要一个允许letters and only
而不是digits
的变量。
该变量可以位于字符串中的任何位置。
看看这个,
$pattern = '~user/(:var)~';
$pattern = str_replace('(:var)', '([a-zA-Z])', $pattern);
// Note, the variable contain both numbers and letters
$test = 'user/dave123';
$r = preg_match($pattern, $test);
var_dump($r); //1 Success (I don't want this)
我想要的只是,
如果变量仅包含字母,则preg_match()
应返回1
,
但如果那个包含至少一个数字,则preg_match()
应立即返回0,
应该定义哪个regex
而不是([a-zA-Z])
以及为什么([a-zA-Z])
匹配数字和字母!?
答案 0 :(得分:6)
正则表达式匹配测试值的这个子字符串:user/d
。
如果要检查整个字符串,请在模式中添加start(^
)和end($
)个锚点:
$pattern = '~^user/(:var)$~';
要检查字符串的开头/结尾 OR 另一个分隔符,例如/
,它将如下所示:
$pattern = '~(?:^|/)user/(:var)(?:$|/)~';
这将迫使它考虑整个值,直到字符串的结尾或下一个/
...阻止您在问题中遇到的部分匹配。
(?:
表示non-capturing group,这意味着额外的()
群组不会在您的匹配结果列表中结束)
您还需要允许[a-zA-Z]
类重复+
,否则它只会匹配单字符用户名:
$pattern = str_replace('(:var)', '([a-zA-Z]+)', $pattern);
答案 1 :(得分:3)
您需要分别使用^
和$
开始结束。
'~^user/(:var)$~'
匹配是因为,您的字符串中包含user
,dave
。
答案 2 :(得分:1)
您的模式意味着“a-z或A-Z之间的任何字符之一”,这就是它匹配的原因。它不提供检查以确定它是否匹配仅,并且它不会匹配重复的字符。
而不是那种方法,为什么不尝试更简单的方法。因为您只想知道字符串是否包含数字:
$haystack = 'user/dave123';
foreach(range(0,9) as $i) {
if (strpos($haystack,$i) === FALSE)) {
return 1;
}
}
return 0;
这将停在找到的第一个号码上。
答案 3 :(得分:0)
模式可能与字符串中的第一个字符匹配,而不是与整个字符串匹配。要匹配整个字符串,请尝试
"/^[a-z]+$/i"
这应该给你一个不区分大小写的字母只匹配整个字符串(^
和$
是字符串的开头和字符串的结尾分隔符)。
还有一些方便的内置PHP函数,如ctype_alpha()
,它们完全相同。