【问题标题】:Regexp: How to match a string that doesn't have any character repeated 3 times?正则表达式:如何匹配没有任何字符重复 3 次的字符串?
【发布时间】:2013-01-17 09:03:08
【问题描述】:

我正在尝试制作一个可以验证输入字符串的模式。验证规则不允许任何字符连续重复超过 3 次。

例如:

Aabcddee - 有效。

Aabcddde - 无效有效,因为有 3 个 d 个字符。

我们的目标是提供一个可以匹配上述示例之一的 RegExp 模式,但不能同时匹配两者。我知道我可以使用诸如([a-z])\1{1,2} 之类的反向引用,但这仅匹配连续字符。我的问题是我无法弄清楚如何为此制作单一模式。我试过这个,但我不太明白为什么它不起作用:

^(([a-z])\1{1,2})+$

在这里,我尝试匹配内部组中重复 1 或 2 次的任何字符,然后如果重复多次,则匹配该内部组。但它不是那样工作的。

谢谢。

【问题讨论】:

  • 你使用什么语言?
  • PCRE RegExp 风格,用于 PHP。
  • 我真的不明白为什么/^([a-z])\1{1,2}$/i 匹配aaa。字符串长度为 3 个字符,比量化的反向引用长。
  • @Aleksandr [a-z]\1{1,2} 匹配 2 或 3 个字符([a-z] 加上相同字符 1 或 2 次)。
  • 正如@Placido 指出的那样,([a-z])\1{2} 将匹配 3 个重复的字符,因此这可能是您要查找的正则表达式:如果字符串与此模式匹配,则它是无效。

标签: regex pcre backreference


【解决方案1】:

检查字符串中没有连续重复 3 次或更多次的字符(任何类型,甚至是换行符):

/^(?!.*(.)\1{2})/s

您还可以检查输入字符串是否与此正则表达式不匹配。在这种情况下,您也可以知道连续重复 3 次或更多次的字符。请注意,这与上面完全相同,只是将负前瞻(?!pattern) 内的正则表达式取出。

/^.*(.)\1{2}/s

如果您想添加验证字符串仅包含来自[a-z] 的字符,并且您认为aaA 无效:

/^(?!.*(.)\1{2})[a-z]+$/i

如您所见,i 标志(不区分大小写)会影响捕获的文本与当前输入的比较方式。

如果您想允许空字符串通过,请将+ 更改为*

如果您想将aaA 视为有效,并且您希望同时允许大小写:

/^(?!.*(.)\1{2})[A-Za-z]+$/

乍一看,可能和上一个一样,但是由于没有i标志,所以捕获的文本不会进行不区分大小写的匹配。

下面是失败的答案,你可以忽略它,但你可以阅读它。


您可以使用此正则表达式检查字符串是否包含 3 个重复字符(任何类型,甚至是新行)。

/^(?!.*(.)(?:.*\1){2})/s

您还可以检查输入字符串是否与此正则表达式不匹配。在这种情况下,您也可以知道字符被重复超过或等于 3 次。请注意,这与上面完全相同,只是将负前瞻(?!pattern) 内的正则表达式取出。

/^.*(.)(?:.*\1){2}/s

如果您想添加验证,该字符串仅包含来自[a-z] 的字符,并且您认为aaA 无效:

/^(?!.*(.)(?:.*\1){2})[a-z]+$/i

如您所见,i 标志(不区分大小写)会影响捕获的文本与当前输入的比较方式。

如果您想将aaA 视为有效,并且您希望同时允许大小写:

/^(?!.*(.)(?:.*\1){2})[A-Za-z]+$/

乍一看,可能和上一个一样,但是由于没有i标志,所以捕获的文本不会进行不区分大小写的匹配。

【讨论】:

  • +1 表示/^(?!.*(.)\1{2})[A-Za-z]+$/。但是,如果 OP 只想匹配正确的 [A-Za-z] 序列(我不确定),那么您的模式不匹配,例如Abaa!!!aa 最多只有 2 个来自 [A-Za-z] 的连续字符。
  • 赞成。感谢您提供的信息,非常有帮助。
  • @speakr:从OP的问题来看,字符串似乎只能包含[A-Za-z],所以我假设A!jashgd被拒绝了。
【解决方案2】:

从你的问题我知道你想匹配

  • 仅由来自[A-Za-z] AND 的字符组成的字符串
  • 仅包含长度为 3 或以上的相同字符的无序列的字符串

那么这个正则表达式应该可以工作:

^(?:([A-Za-z])(?:(?!\1)|\1(?!\1)))+$

(Example in perl)

【讨论】:

  • 将此标记为答案。因为:它匹配Aabcddee,不匹配Aabcddde。谢谢。
猜你喜欢
  • 2016-01-15
  • 1970-01-01
  • 2017-08-31
  • 2010-12-12
  • 2013-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多