2010-03-05 34 views
5

Có cách nào để lấy regex đơn để thỏa mãn điều kiện này không ??làm cách nào để bao gồm boolean AND trong regex?

Tôi đang tìm kiếm một "chữ" mà có ba chữ từ tập MBIPI, thứ tự bất kỳ, nhưng PHẢI chứa I.

tức.

re.match ("[MBDPI] {3}", foo) và "I" trong foo

Vì vậy, đây là kết quả chính xác (trong python bằng cách sử dụng mô-đun lại), nhưng tôi có thể có được điều này từ một regex duy nhất?

>>> for foo in ("MBI", "MIB", "BIM", "BMI", "IBM", "IMB", "MBD"): 
...  print foo, 
...  print re.match("[MBDPI]{3}", foo) and "I" in foo 
MBI True 
MIB True 
BIM True 
BMI True 
IBM True 
IMB True 
MBD False 

with regex Tôi biết tôi có thể sử dụng | như toán tử OR boolean, nhưng có boolean AND equivalent?

hoặc có thể tôi cần một số tra cứu tiến hoặc lùi?

+0

Bạn cũng có thể tìm kiếm ký tự 'I' bằng str.find(). Nguồn: http://docs.python.org/library/stdtypes.html#str.tìm thấy – Dor

Trả lời

2

Hoặc là về điều duy nhất bạn có thể làm:

\b(I[MBDPI]{2}|[MBDPI]I[MBDPI]|[MBDPI]{2}I)\b 

Nhân vật \b boundary zero-chiều rộng. Điều này đảm bảo bạn phù hợp với một cái gì đó là chính xác ba ký tự.

Bạn đang chạy theo các giới hạn đối với những gì mà regular language có thể thực hiện.

Một cách khác là để phù hợp với:

\b[MBDPI]{3}\b 

chụp nhóm đó và sau đó tìm kiếm một I.

Edit: vì lợi ích của việc có một câu trả lời hoàn chỉnh, tôi sẽ thích nghi Jens' answer rằng sử dụng Testing The Same Part of a String for More Than One Requirement:

\b(?=[MBDPI]{3}\b)\w*I\w* 

với kiểm tra biên giới từ để đảm bảo nó chỉ dài ba ký tự.

Đây là giải pháp nâng cao hơn một chút và có thể áp dụng trong nhiều trường hợp hơn nhưng tôi thường ưu tiên dễ đọc hơn (là "hoặc" phiên bản imho).

3

Bạn có thể boolean giả và bằng cách sử dụng lookaheads. Theo http://www.regular-expressions.info/lookaround2.html, điều này sẽ làm việc cho trường hợp của bạn:

"\b(?=[MBDPI]{3}\b)\w*I\w*" 
+0

Nó có thể cần kiểm tra ranh giới từ trên nó nhưng nếu không +1, giải pháp thông minh. – cletus

+0

Tôi sẽ chỉnh sửa điều đó trong ... – Jens

+0

liên kết tuyệt vời, cảm ơn. – user213043

2

Bạn có thể sử dụng lookahead để xem nếu một I hiện diện:

(?=[MBDPI]{0,2}I)[MBDPI]{3} 
0

với regex Tôi biết tôi có thể sử dụng | như toán tử OR boolean, nhưng có boolean AND equivalent?

A và B = không (không phải A hoặc B không) = ([^ A] |?! [^ B])

A và B là biểu thức mà thực sự có thể có các thành viên chung.

Các vấn đề liên quan