Biểu thức chính quy để loại trừ một từ / chuỗi


298

Tôi có một biểu thức chính quy như sau:

^/[a-z0-9]+$

Điều này khớp với các chuỗi như /hellohoặc /hello123.

Tuy nhiên, tôi muốn nó loại trừ một vài giá trị chuỗi như /ignoreme/ignoreme2.

Tôi đã thử một vài biến thể nhưng dường như không thể làm việc được!

Nỗ lực yếu đuối mới nhất của tôi là

^/(((?!ignoreme)|(?!ignoreme2))[a-z0-9])+$

Bất kỳ sự giúp đỡ nào sẽ nhận được sự cảm kích cao :-)


Câu trả lời:


376

Đây là một cách khác (sử dụng một cái nhìn tiêu cực ):

^/(?!ignoreme|ignoreme2|ignoremeN)([a-z0-9]+)$ 

Lưu ý: Chỉ có một biểu thức chụp : ([a-z0-9]+).


1
Rực rỡ, điều đó dường như đã thực hiện các mẹo. Tôi thực sự cần quy tắc này để viết lại url và tôi muốn bỏ qua thư mục "hình ảnh", "css" và "js". Vì vậy, quy tắc của tôi là như sau: ^ / (?! Css | js | hình ảnh) ([az] +) /? (\? (. +))? $ Và nó viết lại thành /Profile.aspx?id=$1&$3 Liệu quy tắc này có hoạt động chính xác và tuyên truyền chuỗi truy vấn không? Vì vậy, nếu ai đó truy cập mydomain.com/hello?abc=123 Tôi muốn viết lại thành mydomain.com/Profile.aspx?id=hello&abc=123 Tôi cũng không chắc về hiệu suất của (. +) Tại kết thúc để nắm bắt chuỗi truy vấn trong yêu cầu ban đầu.
romiem

Âm thanh như thế này là một câu hỏi khác. Regrec mà bạn có trông giống như nó sẽ nắm bắt chuỗi truy vấn - kiểm tra và xem liệu chuỗi truy vấn của bạn có xuất hiện không. Ngoài ra - (\?(.+))?$nên nhanh chóng. Tôi sẽ không lo lắng quá nhiều về tốc độ.
Seth

1
Điều này không hiệu quả với tôi, trong khi giải pháp của Alix Axel đã làm việc. Tôi đang sử dụng java.util.regex.Patternlớp của Java .
Mark Jeronimus

1
Tôi xác nhận reMark của Mark;) - ví dụ: Pycharm dựa trên Java, phải không? Vì vậy, xem xét các biểu thức chính trong tìm kiếm của Pycharm, giải pháp của Alix không hoạt động.
fanny

43

Điều này nên làm điều đó:

^/\b([a-z0-9]+)\b(?<!ignoreme|ignoreme2|ignoreme3)

Bạn có thể thêm bao nhiêu từ bị bỏ qua tùy thích, đây là một triển khai PHP đơn giản:

$ignoredWords = array('ignoreme', 'ignoreme2', 'ignoreme...');

preg_match('~^/\b([a-z0-9]+)\b(?<!' . implode('|', array_map('preg_quote', $ignoredWords)) . ')~i', $string);

tôi nghĩ rằng nhìn phía sau đòi hỏi một mô hình chiều rộng cố định?
simon

2
@AlixAxel Có, nhưng lib regex thông minh hơn sẽ cho phép thay thế với độ dài khác nhau cho các lựa chọn thay thế (và sử dụng dài nhất), miễn là mỗi phương án có độ dài cố định.
ChrisF

Điều này là thông minh, nhưng thất bại đối với tôi nếu từ bị bỏ qua nằm ở cuối của bất kỳ từ nào khác. tức là nếu bạn thêm 'a' làm một trong số các từ bị bỏ qua, thì bất kỳ từ nào kết thúc bằng một đều bị bỏ qua
singmotor

21

Khi bạn muốn loại trừ cả hai từ, bạn cần một cách kết hợp:

^/(?!ignoreme$)(?!ignoreme2$)[a-z0-9]+$

Bây giờ cả hai điều kiện phải đúng (không được phép không biết hoặc không biết 2 ) để có một kết quả khớp.


1
Điều này tương đương với cái ngắn hơn ở trên là cái nhìn tiêu cực của một tập hợp các lựa chọn thay thế.
ChrisF

4
@ChrisF Không, không hẳn. Giải pháp của Seth sẽ không khớp với thứ gì đó giống /ignoremenotnhư /được theo sau ignoreme.
Gumbo
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.