正则表达式非连续字符

时间:2011-01-19 18:54:21

标签: regex

目前我有:

[A-Za-z0-9._%+-]

这匹配任何包含字母,数字和某些特殊字符(._%+-

的字符串

如何更改此项以使其不会与包含特殊字符的字符串连续匹配?

例如,我希望它匹配: foo.bar+testfoo.+bar以及+foo.

但不是: foo..bar+testfoo.bar++testfoo.bar++

4 个答案:

答案 0 :(得分:6)

如果您的工具/语言支持预览,请尝试:

^(?!.*([._%+-])\1)[A-Za-z0-9._%+-]+$

答案 1 :(得分:4)

^(?:[0-9A-Za-z]+|([._%+-])(?!\1))+$

细分:

  • (?: ... )+ - 中的一个或多个:
    • [0-9A-Za-z]+ - 一个或多个字母数字字符
    • ([._%+-]) - 任何允许的非字母数字
      • (?!\1) - 后面没有完全相同的字符

允许:

  • foo
  • foo.+bar
  • -700.bar+baz

组合不允许:

  • foo..bar
  • foo.+bar--baz

每次匹配外部非捕获组并使用否定前瞻(\1 ... {{时,将匹配的非字母数字字符捕获到第一个反向引用((?!)中。 1}})确保相同的字符不会连续出现两次。请注意,并非所有正则表达式都支持负面预测!

答案 2 :(得分:1)

这个怎么样:

^(?!.*[._%+-]{2})[\w.%+-]+$

如果只能重复相同的字符,请使用:

^(?!.*([._%+-])\1)[\w.%+-]+$

答案 3 :(得分:0)

使用PHP的PCRE,您可以这样做:

/^([A-Za-z0-9]|([._%+-])(?!\2))*$/

\2是检测同一符号的重复使用所需的反向引用。我不确定在没有前向断言和后向引用的情况下可以做到这一点,所以我的工作正则表达式进行了测试:

'foo'         => true,
'bar.baz'     => true,
'bar.biz.buz' => true,
'bar.+bar'    => true,
'bar..bar'    => false,
'biz.baz..'   => false,
'..++..'      => false,
'.faf.'       => true,