2011-09-09 30 views
8

Tôi muốn có một biểu hiện thường xuyên để phù hợp với tất cả các:regex tùy chọn lookahead

  1. startabcend
  2. startdef
  3. blahstartghiend
  4. blahstartjklendsomething

và trở abc, def,Lần lượt là 210 và jkl.

Tôi có điều sau đây hoạt động trong trường hợp 1 và 3 nhưng gặp sự cố khi đặt chế độ xem xét tùy chọn.

(?<=start).*(?=end.*) 

Edit:

Hmm. Ví dụ tồi. Trong thực tế, bit ở giữa không phải là số, nhưng được đặt trước bởi một tập hợp các ký tự nhất định và được tùy chọn thành công bởi nó. Tôi đã cập nhật các đầu vào và đầu ra theo yêu cầu và thêm ví dụ thứ 4 để trả lời câu hỏi của ai đó.

Trả lời

8

Đang cố gắng để đọc giữa các dòng, nó có vẻ như thể bạn không muốn lookahead đây, bạn có thực sự muốn không tham lam .*?.

(?<=start).*?(?:end)?$ 

Tôi đoán là bạn đang cố gắng để phù hợp với cái gì đó như "start123end", nhưng không muốn end hoặc start để hiển thị trong các văn bản phù hợp, và do đó bạn có khẳng định lookaround đó để hạn chế .* thường tham lam.

Thay vào đó, bạn chỉ có thể sử dụng biến thể không tham lam và neo đầu bên phải của mẫu bằng $.

(Ngoài ra, nếu bạn có thể sử dụng các nhóm chụp, bạn nên chỉ làm điều đó thay vì:

start(.*?)(end)?$ 

và sau đó chỉ cần lấy giá trị từ nhóm chụp đầu tiên.)

1

Mũi tên tùy chọn không có ý nghĩa:

Nếu tùy chọn thì không sao nếu nó khớp, nhưng cũng không sao nếu nó không khớp. Và kể từ khi một lookahead không mở rộng trận đấu nó đã hoàn toàn không có hiệu lực.

Vì vậy, cú pháp cho bảng điều khiển tùy chọn là chuỗi trống.

+0

Tôi cần trả lại bit ở giữa mà không có hậu tố tùy chọn. –

+0

Vì vậy, bạn nên khớp 'start456otherstuff'? –

+0

không, nhưng nó phải khớp với start456endotherstuff nhưng chỉ trả lại 456. –

0

Tại sao bạn cần lookahead?

start(\d+)\w* 

Xem nó trên rubular

5

Có lẽ như thế này:

(?<=start).*?(?=(?:end|$)) 

này sẽ phù hợp cho đến khi "bắt đầu" và "kết thúc" hoặc đến cuối dòng, bổ sung các lượng hóa có là không tham lam (.*?)

Xem it here on Regexr

Mở rộng ví dụ trên Regexr để không chỉ hoạt động với các chữ số.

2

Chỉ cần một mình thôi thì sẽ không thực hiện được công việc. Hãy thử điều này:

(?<=start)(?:(?!end).)* 

Vị trí trông bạn sau từ "bắt đầu", sau đó phần còn lại sẽ tiêu thụ mọi thứ cho đến khi (nhưng không bao gồm) sự xuất hiện tiếp theo của "kết thúc".

Dưới đây là một demo on Ideone.com

1

nếu "kết thúc" sẽ luôn luôn có mặt, sau đó sử dụng: (?<=start)(.*?)(?=end) như bạn đặt trong OP. Vì bạn nói "làm cho lookahead tùy chọn", sau đó chỉ cần chạy lên cho đến khi có "kết thúc" hoặc vận chuyển trở lại. (?<=start)(.*?)(?=end|\n). Nếu bạn không quan tâm đến việc nắm bắt nhóm "kết thúc", bạn có thể bỏ qua lookahead và làm (?:start)?(.*?)(?:end)? sẽ bắt đầu sau "bắt đầu", nếu nó ở đó và dừng trước khi "kết thúc", nếu nó ở đó. Bạn cũng có thể sử dụng nhiều mẫu "hoặc" có đường ống sau: (?:start|^)(?:end|\n).

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