2017-05-24 107 views
1

我正在处理一个小项目,并且需要正则表达式接受包含给定字母表中的每个字符的字符串至少一次查找包含每个字符的字符串至少一次的Python RegEx

所以对于字母{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)*) 
+0

CAN你张贴无效输入的例子吗? – RomanPerekhrest

+0

@RomanPerekhrest对于列出的示例,任何没有至少一个J,K和L的字符串。因此“JK”,“KLLKK”和“JJLLLJL”将全部被拒绝。 – user3776749

+0

lookahead正则表达式的答案可能比用每个数组字符的字符串查找函数循环要慢。他们都做同样的事情(即从字符串开始),但正则表达式有一些开销状态(如断言组和否定类),会使它变慢。 – sln

回答

6

这是一种典型的用例为一个超前。您可以简单地使用^(?=[^J]*J)(?=[^K]*K)(?=[^L]*L)来检查您的所有条件。如果你的字符串也只能包含这些字符,你可以附加[JKL]+$

+0

完美。我曾经看到过前瞻,但是在思考问题时,这不在我的“心理工具箱”中。 – user3776749

3

如果使用正则表达式是不是你也可以检查单个字符的要求:

text = ... 
alphabet = 'JKL' 
assert all([character in text for character in alphabet]) 

或者,如果你不想让那些没有在字母字符:

assert set(alphabet) == set(text) 
相关问题