2008-11-24 31 views

Trả lời

11

Một số thư viện regex llow lookahead:

somefile(?!16\.txt$).*?\.txt 

Nếu không, bạn vẫn có thể sử dụng nhiều lớp nhân vật:

somefile([^1].|1[^6]|.|.{3,})\.txt 

hay, để đạt được tính di động tối đa:

somefile([^1].|1[^6]|.|....*)\.txt 

[^(16)] có nghĩa là: Phù hợp với bất kỳ ký tự nhưng niềng răng, 1 và 6.

+0

Bạn có thể muốn? trong đó như thế này: somefile (?! 16). *? \. txt –

+0

@Martin Brown: Tại sao? . *? afaik không hợp lệ ở hầu hết các phương ngữ. . có nghĩa là bất kỳ ký tự nào, * không hoặc nhiều lần xuất hiện. Dấu chấm hỏi nên làm gì? – phihag

+0

@phihag:. *? có nghĩa là để làm cho. * không tham lam. Đó là cách sử dụng đặc biệt của dấu chấm hỏi. –

3
somefile_(?!16).*\.txt 

(?! 16) có nghĩa là: Xác nhận rằng không thể khớp với regex "16" bắt đầu từ vị trí đó.

+0

Điều này sẽ vi phạm nếu {bất kỳ} bao gồm dấu chấm: somefile_19700101.archive.txt sẽ không khớp. – phihag

5

Giải pháp tốt nhất đã được đề cập:

somefile_(?!16\.txt$).*\.txt 

này hoạt động, và đủ tham lam để có bất cứ điều gì đến lúc nó trên cùng một dòng. Nếu bạn đã biết, tuy nhiên, bạn muốn có một tên hồ sơ hợp lệ, tôi muốn đề nghị cũng giới hạn ký tự không hợp lệ:

somefile_(?!16)[^?%*:|"<>]*\.txt 

Nếu bạn đang làm việc với một động cơ regex mà không hỗ trợ lookahead, bạn sẽ phải xem xét làm thế nào để tạo nên điều đó! Bạn có thể chia file thành hai nhóm, những người bắt đầu bằng 1, và không được thực hiện bởi 6, và những người bắt đầu với bất cứ điều gì khác:

somefile_(1[^6]|[^1]).*\.txt 

Nếu bạn muốn cho phép somefile_16_stuff.txt nhưng KHÔNG somefile_16.txt , những regex ở trên là không đủ. Bạn sẽ cần phải thiết lập giới hạn của bạn khác nhau:

somefile_(16.|1[^6]|[^1]).*\.txt 

Kết hợp tất cả điều này, và bạn kết thúc với hai khả năng, một trong đó khối các trường hợp duy nhất (somefile_16.txt), và một trong đó khối ra tất cả các gia đình (somefile_16 * .txt). Cá nhân tôi nghĩ rằng bạn thích cái đầu tiên:

somefile_((16[^?%*:|"<>]|1[^6?%*:|"<>]|[^1?%*:|"<>])[^?%*:|"<>]*|1)\.txt 
somefile_((1[^6?%*:|"<>]|[^1?%*:|"<>])[^?%*:|"<>]*|1)\.txt 

Trong phiên bản mà không xoá các ký tự đặc biệt vì vậy nó dễ dàng hơn để đọc:

somefile_((16.|1[^6]|[^1).*|1)\.txt 
somefile_((1[^6]|[^1]).*|1)\.txt 
4

Chấp hành nghiêm chỉnh đặc tả của bạn và thể kén chọn, bạn thay vì phải sử dụng :

^somefile_(?!16\.txt$).*\.txt$ 

nên somefile_1666.txt rằng đó là bất cứ điều gì {} có thể được xuất hiện;)

nhưng đôi khi nó chỉ là dễ đọc hơn để sử dụng ...:

ls | grep -e 'somefile_.*\.txt' | grep -v -e 'somefile_16\.txt' 
2

Đôi khi việc sử dụng hai cụm từ thông dụng trở nên dễ dàng hơn. Đầu tiên hãy tìm mọi thứ bạn muốn, sau đó bỏ qua mọi thứ bạn không làm. Tôi làm điều này tất cả các thời gian trên dòng lệnh, nơi tôi ống một regex được một superset vào regex khác bỏ qua những thứ tôi không muốn.

Nếu mục tiêu là để hoàn thành công việc thay vì tìm được regex hoàn hảo, hãy xem xét cách tiếp cận đó. Nó thường dễ dàng hơn nhiều để viết và hiểu hơn một regex mà làm cho việc sử dụng các tính năng kỳ lạ.

1

Nếu không sử dụng lookahead

somefile_(|.|[^1].+|10|11|12|13|14|15|17|18|19|.{3,}).txt 

Đọc nó thích: somefile_ Tiếp theo một trong hai:

  1. gì.
  2. một ký tự.
  3. bất kỳ một ký tự nào trừ 1 và theo sau là bất kỳ ký tự nào khác.
  4. ba hoặc nhiều ký tự.
  5. hoặc 10 .. 19 lưu ý rằng 16 đã bị bỏ qua.

và cuối cùng theo sau là .txt.

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