2013-08-14 38 views
5

Nếu tôi viếtregex - lẫn lộn về chức năng lookaround

(?<=\()\w+(?=\)) 

cho chuỗi này: (Test) (Test2) (Test3)

tôi sẽ nhận được: Kiểm tra Test2 Test3

Điều đó làm cho cảm giác .

Nếu tôi viết

\w+ (?<=\()\w+(?=\)) 

Đối với chuỗi này: LTE (Test)

nó sẽ trả về không có gì .. vấn đề ở đây là gì?

Vui lòng giải thích rõ ràng regex của bạn vì có thể khó đọc.

+0

sử dụng http://gskinner.com/RegExr/: di chuột qua mã regex của bạn để xem giải thích rõ ràng. Xem thêm http://regex101.com/r/zE8qZ8 – hexicle

+0

Tôi đã sử dụng regexr để kiểm tra điều này ngay từ đầu. vẫn không làm cho nó rõ ràng với tôi tại sao nó không làm việc – hamobi

Trả lời

5

Các giải pháp không tiêu thụ các ký tự!

Dưới đây là một từng bước cách nào để xem nó (có thể không phải là tốt nhất, nhưng đó là cách tôi giải thích nó anyway):

nhân vật đầu tiên là L, động cơ regex so sánh nó với \w+ và đồng ý rằng đó là một trận đấu. Điều tương tự cũng xảy ra cho T, sau đó E.

Ở khoảng trống, công cụ regex nhìn thấy khoảng trống trong cụm từ thông dụng, điều đó cũng tốt.

Tiếp theo là dấu mở đầu, nhưng regex nhìn thấy gì? Hãy nhớ rằng các cách giải thích không tiêu thụ các ký tự, sao cho số \( trong (?<=\() không thực sự bị tiêu thụ và \( không khớp với những gì phù hợp với \w+!

Bạn có thể nghĩ về regex thực sự tiêu thụ các ký tự đó: \w+ \w+, nhưng với điều kiện trên số \w+ thứ hai, phải tìm thấy giữa các ký tự. Điều kiện có thể được thỏa mãn, nhưng chính biểu thức không khớp với bất kỳ dấu ngoặc đơn nào!

Để làm cho nó phù hợp, bạn nên thêm dấu ngoặc:

\w+ \((?<=\()\w+(?=\))\) 

Sau khi nhìn thấy và phù hợp với không gian, động cơ regex thấy (, mà đồng ý với các biểu hiện cung cấp, nó di chuyển về phía trước.

Động cơ sau đó sẽ thấy T. Đầu tiên, nó có khớp với ký tự tiếp theo không, \w+? Có, thứ hai, là có một paren mở trước khi nó? Vâng.

Trước khi tiến về phía trước, nó nhìn thấy một dấu hiệu tích cực. Có một paren đóng ngay phía trước? Không, có e, nhưng vẫn có thể đáp ứng được \w+, vì vậy, nó khớp với e với \w khác. Điều này tiếp tục như thế này cho đến t. Có paren đóng sau t không? Có, do đó tiến hành kiểm tra tiếp theo.

Nó gặp một dấu ngoặc đóng, được so khớp với dấu ngoặc đóng trong biểu thức (lưu ý rằng dấu ngoặc đóng bằng chữ có thể bị bỏ ở đây và bạn sẽ khớp với LTE (Test thay thế).

Nhưng với tất cả điều này, nó có thể được chỉ là tốt đẹp đã bỏ lookarounds:

\w+ \(\w+\) 

Bởi vì họ thêm căng thẳng thêm về động cơ và mặc dù nó không phải là nhìn thấy được trên quy mô nhỏ, nó có thể được đáng kể trên một chuỗi lớn hơn.

Hy vọng rằng, nó sẽ giúp, ngay cả khi đó là một chút!

+0

để về cơ bản .. một cantar lookaround thực sự được sử dụng ở trung tâm của một regex? trong ví dụ đầu tiên của tôi, tôi đang nhận được tất cả các "kiểm tra" mà không có phép thuật, nhưng tôi sẽ không nhận được LTE. Nếu tôi muốn có LTE, thì tôi chỉ nên nói rõ ràng rằng có những mệnh lệnh? Tôi không hoàn toàn hiểu được. – hamobi

+0

@hamobi Bạn _can_ sử dụng nó ở trung tâm của một regex, nhưng cho dù đó là hữu ích hay không sẽ là câu hỏi. Thông thường, hãy cố gắng tránh chúng càng nhiều càng tốt và chỉ sử dụng chúng nếu cần. Họ thường mất nhiều thời gian xử lý hơn. – Jerry

2

Lookahead và lookbehind là "zero-width assertions", chúng không tiêu thụ các ký tự trong chuỗi, nhưng chỉ xác nhận xem có khớp được hay không. Mẫu thứ hai của bạn cố gắng tìm cấu trúc <word1><space><word2>, nhưng nó cũng hy vọng rằng <word2> được bao quanh bởi dấu ngoặc đơn. Nó sẽ không khớp với bất cứ thứ gì, vì ký tự duy nhất nó chấp nhận trước <word2><space>! Tôi chỉ cần viết các dấu ngoặc đơn trực tiếp vào mẫu: (\w+) \((\w+)\). Tôi đã thử nó, và nó mang lại cho tôi LTETest.