我需要匹配包含@
,#
及其中任何数字的文字。只要字符在文本中,字符就可以处于随机位置。鉴于此输入:
abc@#d9
a9b#c@d
@@abc#9
abc9d@@
a#b#c@d
正则表达式应匹配前3行。目前我的正则表达是:
/@.*?#.*?[0-9]/
哪个不起作用,因为它只会按顺序匹配三个字符。如何以随机顺序匹配三个字符?
答案 0 :(得分:3)
找到一个丑陋的正则表达式,如果你真的必须使用一个:
/(?=.*@)(?=.*#)(?=.*[0-9]).*/
正则表达式基本上使用了他们所谓的lookahead
http://www.regular-expressions.info/lookaround.html
上述链接中的一个简单案例是尝试匹配q
,然后u
,q(?=u)
,这就是为什么它被称为lookahead
,它找到{{} 1}}后跟q
。
让我们采取您的一个有效案例:u
第一个预测是a9b#c@d
,其中指出:匹配任何内容,然后是(?=.*@)
。所以它确实是字符串@
,因为必须丢弃前瞻的匹配,引擎会回到字符串的开头,即a9b#c
。然后它转到
a
,其中说明:匹配(?=.*#)
后面的所有内容,然后在#
找到它。使用前瞻和a9b
之间的区别基本上就是退步。
从上面的链接:
让我们再看看内部,以确保你理解 前瞻的含义。让我们应用q(?= u)i来退出。我有 使前瞻性变得积极,并在其后面加上一个代币。再次,q 匹配q和u匹配你。 同样,前瞻的匹配必须是 丢弃,所以引擎从字符串中的i退回到u。该 前瞻是成功的,所以发动机继续我。但是我不能 匹配你所以这场比赛尝试失败了。所有剩余的尝试都将失败 同样,因为字符串中没有更多的q。
它很难看,因为它很难维护......你基本上在括号内有3个不同的子正则表达式。
答案 1 :(得分:0)
使用单独的表达式确保存在@和#。一旦它们被删除,并匹配其余的字符/数字。
答案 2 :(得分:0)
决定我最好把它写成答案:
$text = "a9b#c@d";
$themAll = "#@";
$themAny = "0123456789";
echo (strspn($themAll, $text)==strlen($themAll) && strpbrk($text, $themAny));
对于维护和一些(有限的)扩展,这应该是容易的,特别是$themAll
列出更长的时间。