2017-05-24 72 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) 
相關問題