【问题标题】:Regex non-consecutive chars正则表达式非连续字符
【发布时间】:2011-01-20 03:32:39
【问题描述】:

目前我有:

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

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

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

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

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

【问题讨论】:

  • 其他情况:+foo.barfoo.+barfoo.bar+ 应该匹配吗?
  • @Ben:显然不是第二个。
  • @SilentGhost — 他的示例只连续显示了两个 same 特殊字符,所以我认为值得一问。 ;-)
  • @Ben @SilentGhost - 我编辑了原帖。谢谢。

标签: regex


【解决方案1】:

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

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

【讨论】:

  • +1 表示只有一个前向断言的有效答案(而不是我的为每个特殊字符循环)...
【解决方案2】:
^(?:[0-9A-Za-z]+|([._%+-])(?!\1))+$

分解:

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

允许:

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

不允许:

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

每次匹配外部非捕获组时,它通过将匹配的非字母数字字符捕获到第一个反向引用 (\1) 并使用负前瞻 ((?! ... )) 来制作确保同一字符不会连续出现两次。请注意,并非所有正则表达式风格都支持负前瞻!

【讨论】:

  • foo.+bar 似乎是有效的(请参阅 Gumbo 回答下的 bjacobs 评论)
  • @Bart — 嗯……那么我想我会等待更多的澄清,然后再试一试。 :-)
【解决方案3】:

这个怎么样:

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

如果只有同一个字符不能重复,则使用:

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

【讨论】:

  • 这与似乎有效的 foo.+bar 不匹配(请参阅 Gumbo 回答下的 bjacobs 评论)。
【解决方案4】:

使用 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,

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-20
    相关资源
    最近更新 更多