Làm thế nào để phủ nhận toàn bộ regex?


95

Tôi có một regex, ví dụ (ma|(t){1}). Nó phù hợp matkhông khớp bla.

Tôi muốn phủ nhận regex, do đó nó phải phù hợp blavà không mat, bằng cách thêm một cái gì đó để regex này . Tôi biết tôi có thể viết bla, tuy nhiên regex thực tế phức tạp hơn.


5
Như một bên, {1}là hoàn toàn vô dụng. (Nếu bạn nghĩ rằng nó cung cấp một số giá trị, tại sao bạn không viết ((m{1}a{1}){1}|(t){1}){1}?)
tripleee

Câu trả lời:


100

Sử dụng cách nhìn nhận tiêu cực: (?!pattern)

Cách nhìn tích cực có thể được sử dụng để khẳng định rằng một mẫu phù hợp. Cách nhìn tiêu cực thì ngược lại: nó được sử dụng để khẳng định rằng một mẫu KHÔNG phù hợp. Một số hương vị hỗ trợ khẳng định; một số giới hạn về ngoại hình, v.v.

Liên kết đến regular-expressions.info

Xem thêm

Thêm ví dụ

Đây là những nỗ lực đưa ra các giải pháp regex cho các vấn đề về đồ chơi dưới dạng bài tập; chúng nên mang tính giáo dục nếu bạn đang cố gắng tìm hiểu các cách khác nhau mà bạn có thể sử dụng các cách nhìn xung quanh (lồng chúng, sử dụng chúng để chụp, v.v.):


2
Regular-expressions.info là một nguồn tài nguyên tuyệt vời cho tất cả mọi thứ regex.
Freiheit

Tất cả những gì có lookaround hỗ trợ? Không hoạt động với grep.
Lazer

Pattern.compile("(?!(a.*b))").matcher("xab").matches()nên được true, phải không?
Karl Richter

4
Tôi có vẻ như điều này không đúng, hãy xem stackoverflow.com/questions/8610743/… để có phương án thay thế chính xác.
Karl Richter

56

Giả sử bạn chỉ muốn không cho phép các chuỗi hoàn toàn khớp với regex (tức mmblalà được, nhưng mmkhông được), đây là những gì bạn muốn:

^(?!(?:m{2}|t)$).*$

(?!(?:m{2}|t)$)là một tiêu cực lookahead ; nó cho biết "bắt đầu từ vị trí hiện tại, một vài ký tự tiếp theo không phải mm hoặc t, theo sau là cuối chuỗi." Bắt đầu neo ( ^) ở đầu đảm bảo rằng lookahead được áp dụng ở đầu chuỗi. Nếu điều đó thành công, .*tiếp tục và sử dụng chuỗi.

FYI, nếu bạn đang sử dụng matches()phương pháp của Java , bạn không thực sự cần cái ^và cái cuối cùng $, nhưng chúng không gây hại gì. Tuy nhiên, $bên trong lookahead là bắt buộc.


2
Phần hữu ích nhất của câu trả lời này là bạn phải thêm .*vào cuối regex của mình, nếu không nó sẽ từ chối mọi chuỗi.
Rav

2
Bên $ trong lookahead phủ định, VÀ .*ở cuối đều là các bit quan trọng. Như mọi khi với REs, một bộ bài kiểm tra đơn vị mạnh mẽ là hoàn toàn quan trọng để làm cho nó đúng. Câu trả lời này đúng 100%.
Tom Dibble

1
\b(?=\w)(?!(ma|(t){1}))\b(\w*)

đây là cho regex đã cho.
\ b là để tìm ranh giới từ.
cái nhìn tích cực về phía trước (? = \ w) ở đây để tránh khoảng trắng.
cái nhìn tiêu cực về phía trước so với regex ban đầu là để ngăn chặn các kết quả trùng khớp của nó.
và cuối cùng (\ w *) là để bắt tất cả các từ còn lại.
nhóm sẽ giữ các từ là nhóm 3.
mẫu đơn giản (?!) sẽ không hoạt động vì bất kỳ chuỗi con nào sẽ khớp với
^ (?! (?: m {2} | t) $) đơn giản. * $ will không hoạt động vì độ chi tiết của nó là đầy đủ các dòng

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.