2009-06-02 30 views
49

Tôi có một công cụ mẫu python sử dụng rất nhiều regexp. Nó sử dụng kết nối như:Cú pháp biểu thức chính quy cho "khớp không có gì"?

re.compile(regexp1 + "|" + regexp2 + "*|" + regexp3 + "+") 

Tôi có thể sửa đổi từng phần riêng lẻ (regexp1, regexp2, v.v).

Có biểu thức nhỏ và nhẹ nào không khớp với nội dung nào mà tôi có thể sử dụng bên trong mẫu mà tôi không muốn bất kỳ kết quả nào khớp không? Thật không may, đôi khi '+' hoặc '*' được gắn vào nguyên tử regexp vì vậy tôi không thể sử dụng chuỗi rỗng - lỗi "không có gì để lặp lại" sẽ tăng lên.

+1

http://stackoverflow.com/questions/1723182/a-regex-that-will-never-be-matched-by-anything –

Trả lời

76

Đây không phải phù hợp với bất cứ điều gì:

re.compile('$^') 

Vì vậy, nếu bạn thay thế regexp1, regexp2 và regexp3 với '$ ^' nó sẽ không thể tìm thấy một trận đấu. Trừ khi bạn đang sử dụng chế độ đa dòng.


Sau khi một số xét nghiệm Tôi tìm thấy một giải pháp tốt hơn

re.compile('a^') 

Nó là không thể để phù hợp và sẽ thất bại sớm hơn so với giải pháp trước đây. Bạn có thể thay thế bằng bất kỳ ký tự nào khác và sẽ luôn không thể đối sánh

+0

Điều đó sẽ không khớp với bất kỳ thứ gì chắc chắn và nhẹ cho động cơ regexp để xử lý? (không muốn stub của tôi regexps để ăn rất nhiều cpu) – grigoryvp

+0

@Eye của địa ngục. Nó phải nhẹ. Điều này sẽ cố gắng để phù hợp với một kết thúc dòng theo sau là một bắt đầu dòng. Điều đó là không thể trong một dòng. –

+1

Nhưng có thể với nhiều dòng khóa học (tùy thuộc vào nếu cờ được kích hoạt) - cho một giải pháp hoạt động cho dù cờ được bật hay không, hãy xem câu trả lời của tôi. –

2

Có thể '.{0}'?

+0

Sẽ trả về đối tượng đối sánh – grigoryvp

3
"()" 

không khớp và không có gì.

+0

Điều này sẽ khớp với một chuỗi trống. Nó phụ thuộc vào những gì @Eye of Hell đang yêu cầu. Nếu anh ta không muốn trận đấu chút nào thì nó sẽ không hoạt động. –

+3

Không - điều này phù hợp với bất cứ điều gì nhưng được coi là một mô hình xấu trong nhiều triển khai regex (phụ thuộc vào cờ đôi khi) – ShuggyCoUk

+0

Không muốn phù hợp với bất cứ điều gì. Tôi sẽ kiểm tra cách python diễn giải "()". – grigoryvp

15

Để phù hợp với một chuỗi rỗng - ngay cả trong chế độ multiline - bạn có thể sử dụng \A\Z, vì vậy:

re.compile('\A\Z|\A\Z*|\A\Z+') 

Sự khác biệt là \A\Z là sự khởi đầu và kết thúc của chuỗi, trong khi ^$ những có thể khớp với bắt đầu/kết thúc của dòng, vì vậy $^|$^*|$^+ có khả năng khớp với một chuỗi chứa các dòng mới (nếu cờ được bật).

Và thất bại để phù hợp với bất cứ điều gì (thậm chí là một chuỗi rỗng), chỉ cần cố gắng để tìm nội dung trước khi bắt đầu của chuỗi, ví dụ:

re.compile('.\A|.\A*|.\A+') 

Vì không có nhân vật có thể đến trước \ A (theo định nghĩa) , điều này sẽ luôn không khớp.

+0

Của bạn trông đẹp hơn tôi vì tôi cho rằng nó sẽ thoát ra nhanh hơn sử dụng cuối dòng. – ShuggyCoUk

+0

Peter, bạn sử dụng \ z (chữ thường) trong khi hướng dẫn bỏ túi Python cho tôi biết xác nhận cuối chuỗi là \ Z (chữ hoa)? – ThomasH

+0

ThomasH, cả hai đều là kết thúc của chuỗi, nhưng phiên bản chữ hoa cho phép một dòng mới trong khi chữ thường không. –

1

Bạn có thể sử dụng
\z..
Đây là phần cuối tuyệt đối của chuỗi, sau đó là hai bất cứ điều gì

Nếu + hoặc * được tacked ở cuối dòng này vẫn hoạt động từ chối để phù hợp với bất cứ điều gì

0

Hoặc , sử dụng một số danh sách hiểu để loại bỏ các mục regexp vô ích và tham gia để đặt chúng lại với nhau.Một cái gì đó như:

re.compile('|'.join([x for x in [regexp1, regexp2, ...] if x != None])) 

Hãy chắc chắn để thêm một số ý kiến ​​bên cạnh đó dòng mã mặc dù :-)

23

(?!) nên luôn luôn thất bại để phù hợp. Đó là nhìn phía trước không có chiều rộng bằng không. Nếu những gì nằm trong dấu ngoặc đơn thì toàn bộ kết quả sẽ không thành công. Cho rằng nó không có gì trong đó, nó sẽ thất bại trận đấu cho bất cứ điều gì (bao gồm cả không có gì).

+3

Phải, tôi đã chỉ cần đăng bài này quá.Đây là cách tốt nhất, nếu ngôn ngữ của bạn hỗ trợ lookaheads. (? =) khớp với mọi chuỗi. –

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