我仍然试图掌握正则表达式模式,只是经过一点点仔细检查,如果有人不介意的话!
我有一个字符串,应该包含:
ABCD1EFGH2IJKL3MNOP4QRST5
或ABCD1-EFGH2-IJKL3-MNOP4-QRST51
我可以使用ctype_alnum和strlen函数匹配前两个。但是,对于最后一个,我认为我需要使用正则表达式和preg_match
。
我在regex101.com进行了审核,并提出了以下建议:
preg_match('^([A-Za-z0-9]{5})+-+([A-Za-z0-9]{5})+-+([A-Za-z0-9]{5})+-([A-Za-z0-9]{5})+-+([A-Za-z0-9]{5})', $str);
这似乎与我正在寻找的相匹配。 我希望字符串只包含以许可证编号开头的字符串的完全匹配,并且除了混合大写/小写字母和任何顺序的数字以及每组5个字符之间的连字符之外什么都不包含(所以总共29个字符 - 我不想要任何进一步的比赛)。在29位数字键之前或之后没有空格,没有其他字符和其他内容。
上述工作是否可以,不允许任何其他组合?它会停止检查29个字符吗?我不确定是否有更简单的方法在正则表达式中表达这一点?
谢谢你的时间!
答案 0 :(得分:2)
重点是你需要使用^
(字符串的开头)和$
(字符串的结尾)锚点。此外,当您在+
之后使用(...)
时,您允许(...)
内的整个子模式重复一次或多次。因此,您需要删除+
并添加$
锚点。此外,您需要正则表达式分隔符,以便您的正则表达式在PHP preg_match
中工作。我更喜欢~
,以免逃避/
。也许这不是这种情况,但这是一种习惯。
因此,正则表达式看起来像
'~^[A-Za-z0-9]{5}(?:-[A-Za-z0-9]{5}){4}$~'
请参阅regex demo
(?:-[A-Za-z0-9]{5}){4}
匹配-[A-Za-z0-9]{5}
子模式的4次出现。 (?:...)
是一个非捕获组,其匹配的文本不会存储在任何缓冲区中(与捕获组不同)。
请参阅IDEONE demo:
$re = '~^[A-Za-z0-9]{5}(?:-[A-Za-z0-9]{5}){4}$~';
$str = "ABCD1-EFGH2-IJKL3-MNOP4-QRST5";
if (preg_match($re, $str, $matches)) {
echo "Matched!";
}
答案 1 :(得分:1)
怎么样:
preg_match('/^([a-z0-9]{5})(?:-(?1)){4}$/i', $str);
<强>解释强>
/ : regex delimiter
^ : begining of string
( : begin group 1
[a-z0-9]{5} : exactly 5 alphanum.
) : end of group 1
(?: : begin NON capture group
- : a dash
(?1) : same as definition in group 1 (ie. [a-z0-9]{5})
){4} : this group must be repeated 4 times
$ : end of string
/i : regex delimiter with case insensitive modifier