2011-09-22 30 views
11

Ví dụ:Trình định lượng {0} có ý nghĩa trong một số tình huống không?

/(?: Foo) {0} bar/

tôi thấy cái gì như thế này trong câu trả lời khác. Lúc đầu, tôi nghĩ "nên là gì", nhưng sau đó, "OK có thể có ý nghĩa, một cái nhìn tiêu cực phía sau", do đó, Foo không được phép trước bar, nhưng điều này không hoạt động.

Bạn có thể xem số này here on Regexr: Chỉ khớp với bar nhưng nó cũng khớp với số bar trong Foobar.
Khi tôi thêm một neo cho sự bắt đầu của hàng:

/^(?:Foo){0}bar/ 

nó hoạt động như tôi mong đợi. Nó chỉ phù hợp với bar và không phải là bar trong Foobar.

Nhưng đó chính xác là hành vi tương tự như khi tôi chỉ sử dụng /bar/ hoặc /^bar/.

Định lượng số {0} chỉ là tác dụng phụ vô dụng, hay thực sự có một hành vi hữu ích cho điều đó?

Trả lời

11

tốt sử dụng {0}. Nó cho phép bạn xác định các nhóm mà bạn không có ý định chụp tại thời điểm. Điều này có thể hữu ích trong một số trường hợp:

  • Cách sử dụng tốt nhất nhóm trong biểu thức chính quy đệ quy (hoặc các cấu trúc kỳ lạ khác). Perl, ví dụ, có (?(DEFINE)) cho cùng một sử dụng.
    Một ví dụ nhanh chóng - trong PHP, điều này sẽ phù hợp với barFoo (working example):

    preg_match("/(?:(Foo)){0}bar(?1)/", "barFoo", $matches); 
    
  • Thêm một nhóm bắt thất bại (đặt tên hoặc số) đến các trận đấu kết quả.

  • Giữ các chỉ số của tất cả các nhóm còn nguyên vẹn trong trường hợp mẫu được cấu trúc lại.

Ít sử dụng tốt, như Peter gợi ý rất hữu ích trong:

  • mẫu tạo.
  • Dễ đọc - Các mẫu có bản sao nhất định, trong đó {0}{1} có thể dẫn đến suy nghĩ đúng hướng. (OK, không phải là điểm tốt nhất)

Đây là tất cả các trường hợp hiếm hoi và trong hầu hết các mẫu, đó là một sai lầm.

+0

Thật tuyệt vời, Kobi. Điều này chỉ hữu ích trong một động cơ có các chương trình con nhưng không phải là '(? (DEFINE))', tôi nghĩ đó chỉ là Ruby và có lẽ Python với mô-đun 'regex'. Thử nghiệm trong Ruby: '(? :(Foo)) {0} thanh \ g <1>' +1000! – zx81

+1

Trong trường hợp bất kỳ ai quan tâm, không hoạt động trong Python với mô đun 'regex'. Nhưng đến với phương án này, nó hoạt động: '(? :(Foo) $ ^)? Bar (? 1)' – zx81

2

Trong biểu thức thông thường truyền thống, /x{0}/ (language = {x n: x = 0}) có nghĩa là "trận đấu chính xác 0 của x", đó là những điều tương tự như // (language = {Λ}). Vì hai số này tương đương nhau, bạn có thể xóa bất kỳ số /x{0}/ nào bạn tìm thấy nằm xung quanh.

Nhưng PCRE và các phần mở rộng khác để biểu thức chính quy có thể nhận được khá byzantine. Tôi sẽ không ngạc nhiên nếu /x{0}/ đã làm điều gì đó trong Perl. Tôi sẽ ghê tởm, nhưng không ngạc nhiên.

Tôi nghĩ rằng đó có thể là một số tạo phẩm của chương trình tự động tạo biểu thức chính quy nhưng không đơn giản hóa chúng. Đó là một sự xấu hổ, vì nó rất dễ dàng để viết các chương trình đơn giản hóa các biểu thức thông thường.

+0

_ "Tôi sẽ ghê tởm, nhưng không ngạc nhiên." _ :) –

+0

Có thực sự dễ dàng để viết các chương trình đơn giản hóa các biểu thức chính quy không? Nghe có vẻ thú vị ... – Kobi

3

Số lần lặp lại rõ ràng bằng 0 có thể hữu ích trong các cụm từ thông dụng được tạo tự động. Bạn tránh viết mã một trường hợp đặc biệt để không lặp lại theo cách này.

2

Tôi không thể nghĩ ra một lý do chính đáng để sử dụng x{0}. Nhưng tôi có thể nghĩ ra một số lý do tại sao cần tránh:

  • Nó vô ích vì nó luôn phù hợp.
  • Nó làm chậm động cơ regex xuống (trừ khi regex được biên dịch trước).
  • Đây có thể là dấu hiệu của sự hiểu lầm của tác giả regex.

tôi sẵn sàng đặt cược rằng người viết (?:foo){0}cố gắng để nói "chắc chắn rằng foo không phù hợp ở đây", trong đó tất nhiên không vì chuỗi rỗng luôn có thể được xuất hiện, cho dù foo có hay không. Đó là những gì khẳng định tiêu cực. (?<!foo)bar v.v.

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