如何使用正则表达式以随机顺序匹配所需字符?

时间:2012-05-31 05:53:22

标签: php regex

我需要匹配包含@#及其中任何数字的文字。只要字符在文本中,字符就可以处于随机位置。鉴于此输入:

abc@#d9
a9b#c@d
@@abc#9
abc9d@@
a#b#c@d

正则表达式应匹配前3行。目前我的正则表达是:

/@.*?#.*?[0-9]/

哪个不起作用,因为它只会按顺序匹配三个字符。如何以随机顺序匹配三个字符?

3 个答案:

答案 0 :(得分:3)

找到一个丑陋的正则表达式,如果你真的必须使用一个:

/(?=.*@)(?=.*#)(?=.*[0-9]).*/

http://jsfiddle.net/BP53f/2/

正则表达式基本上使用了他们所谓的lookahead

http://www.regular-expressions.info/lookaround.html

上述链接中的一个简单案例是尝试匹配q,然后uq(?=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列出更长的时间。