【发布时间】:2017-05-24 20:16:29
【问题描述】:
我正在做一个小项目,需要正则表达式来接受包含给定字母表中每个字符的字符串至少一次。
所以对于字母表{J, K, L},我需要一个正则表达式,它接受包含J 一次或多次和K 一次或多次,以及L 一次或多次的字符串,以任意顺序,任意之前、之后或中间的重复字符数量。
我对 RegEx 非常缺乏经验,因此很难找到许多问题的“横向思维”解决方案。因此,我的第一种方法是相当蛮力的:我采用了每个可能的“基本”字符串,例如,
JKL, JLK, KJL, KLJ, LKJ, LJK
并允许任何可以从这些起点之一建立的字符串。然而,生成的正则表达式*(尽管可以工作)最终会很长并且包含很多冗余。更不用说,一旦字母表包含多个字符,这种方法就变得完全站不住脚了。
我花了几个小时试图找到一种更优雅的方法,但我还没有找到一种仍然接受所有可能字符串的方法。有没有一种方法或技术可以让我以更优雅和可扩展的方式完成这项工作(适用于更大的字母表)?
*作为参考,我列出示例的正则表达式:
((J|K|L)*J(J|K|L)*K(J|K|L)*L(J|K|L)*)|
((J|K|L)*J(J|K|L)*L(J|K|L)*K(J|K|L)*)|
((J|K|L)*K(J|K|L)*J(J|K|L)*L(J|K|L)*)|
((J|K|L)*K(J|K|L)*L(J|K|L)*J(J|K|L)*)|
((J|K|L)*L(J|K|L)*J(J|K|L)*K(J|K|L)*)|
((J|K|L)*L(J|K|L)*K(J|K|L)*J(J|K|L)*)
【问题讨论】:
-
你能发布无效输入的例子吗?
-
@RomanPerekhrest 对于列出的示例,任何不包含至少一个 J、K 和 L 的字符串。因此,“JK”、“KLLKK”和“JJLLLJL”都会被拒绝。
-
前瞻正则表达式答案可能比使用字符串查找函数为每个数组字符循环要慢。它们都做同样的事情(即从字符串开头开始),但是正则表达式有一些开销状态(如断言组和否定类)会使其变慢。
-
@sln 感谢您的提示。这个项目主要是为了试验 RegEx,但我以后会记住这一点。
-
如果您只是想弄乱正则表达式并寻找与断言不同的方法,请使用新的 regex 模块并在其上尝试
(?:.*?(?:((?(1)(?!))j)|((?(2)(?!))k)|((?(3)(?!))l))){3}因为断言不是他们真的在试验吗?尝试和benchmark 实验,你可能会对你的发现感到惊讶。