2012-09-19 23 views
7

Tôi có chuỗi sau:Regex thay thế văn bản nhưng loại trừ khi văn bản là giữa từ khóa cụ thể

Lorem ipsum Test dolor sit amet, consetetur sadipscing elitr, sed diam nonumy <a href="http://Test.com/url">Test</a> eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd sed Test dolores et ea rebum. Stet clita kasd gubergren, no sea <a href="http://url.com">Test xyz</a> takimata sanctus est Lorem ipsum dolor sit amet. 

Bây giờ tôi sẽ thay thế các chuỗi bên ngoài của thẻ một không giữa các thẻ (ví dụ như thay thế bằng '1234' 'Test').

Lorem ipsum 1234 dolor sit amet, consetetur sadipscing elitr, sed diam nonumy <a href="http://Test.com/url">Test</a> eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd sed 1234 dolores et ea rebum. Stet clita kasd gubergren, no sea <a href="http://url.com">Test xyz</a> takimata sanctus est Lorem ipsum dolor sit amet. 

tôi bắt đầu với regex này: (?!<a[^>]*>)(Test)([^<])(?!</a>)

Nhưng hai vấn đề không được giải quyết:

  1. Văn bản 'thử nghiệm' cũng được thay thế bên Tags (ví dụ)
  2. Liệu các văn bản giữa thẻ không khớp chính xác với văn bản được tìm kiếm, nó cũng sẽ được thay thế (ví dụ: <a href="http://url">Test xyz</a>)

Tôi hy vọng ai đó có một giải pháp để giải quyết vấn đề này.

Trả lời

9
(?!<a[^>]*?>)(Test)(?![^<]*?</a>) 

giống như zb226, nhưng tối ưu hóa với một trận đấu lười biếng

Ngoài ra, sử dụng regexes trên HTML thô là không được khuyến khích.

+0

Tôi cũng đã thêm cờ \ b để phù hợp với một ranh giới từ: (?!? ] *>) (\ bTest \ b) (?! [^ <]*?) – Weri

+0

Điều đó sẽ cung cấp cho trình tối ưu hóa regex nhiều hơn để làm việc. Nó cũng không nên ảnh hưởng xấu đến các trận đấu của bạn, miễn là '_Test_, _Test hoặc Test_' không có trong tài liệu của bạn (và giả sử bạn sẽ không quan tâm để phù hợp với chúng nếu chúng). – protist

+0

Các lookaheaed trước khi thử nghiệm và trận đấu lười biếng là vô nghĩa. Xem câu trả lời của tôi. – Adam

3

này nên làm như lừa:

(?!<a[^>]*>)(Test)(?![^<]*</a>) 

Hãy thử nó cho mình on regexr.

2

Hồi sinh câu hỏi cổ này vì nó có một giải pháp đơn giản chưa được đề cập.

Với tất cả các tuyên bố từ chối trách nhiệm về việc sử dụng regex để phân tích cú pháp html, đây là một cách đơn giản để thực hiện.

Phương pháp Perl/PCRE

<a[^>]*>[^<]*<\/a(*SKIP)(*F)|Test 

demo

Giải pháp chung

<a[^>]*>[^<]*<\/a|(Test) 

Trong phiên bản này, văn bản phải được thay thế là bị bắt trong nhóm 1 và thay thế được thực hiện bởi một cuộc gọi lại đơn giản hoặc lambda.

demo

Reference

  1. How to match pattern except in situations s1, s2, s3
  2. Để thực hiện đang xem các mẫu mã trong How to match a pattern unless...
+0

Phần quan trọng nhất đối với tôi là phải biết '$ thay = preg_replace_callback ( \t $ regex, \t function ($ m) {if (trống ($ m [1])) return $ m [0]; \t \t \t \t \t người khác trả lại "Siêu nhân";}, \t $ subject); Vì vậy, tôi cần trả về 'm [0]' nếu 'm [1]' trống. Thực sự tốt đẹp để biết. Cảm ơn bạn! – mgutt

4

Nó là vô nghĩa để đặt một lookahead trước trận đấu.Vì vậy, sau đây là tương đương với sinh vật đơn bào câu trả lời:

(Test)(?![^<]*?</a>) 

cũng kể từ < không được phép trận đấu lười biếng ? là không cần thiết, vì vậy nó cũng tương đương với

(Test)(?![^<]*</a>) 

này sẽ chọn tất cả Test mà không phải là tiếp theo an </a> không có ký hiệu < ở giữa. Đây là lý do tại sao Kiểm tra xuất hiện trước hoặc sau bất kỳ <a ...> .. </a> nào sẽ được thay thế.

Tuy nhiên, lưu ý rằng

Lorem Test dolor <a href="http://Test.com/url">Test <strong>dolor</strong></a> eirmod 

sẽ được thay đổi để

Lorem 1234 dolor <a href="http://1234.com/url">1234 <strong>dolor</strong></a> eirmod 

Để bắt mà bạn có thể thay đổi regex của bạn để

(Test)(?!(.(?!<a))*?</a>) 

mà làm như sau:

Chọn mọi từ Test không theo sau một chuỗi ***</a> trong đó mỗi ký tự trong *** không được theo sau bởi <a.

Lưu ý rằng ở đây, kết hợp lười biếng ? có ý nghĩa.

sinh vật đơn bào nói

Ngoài ra, sử dụng regexes trên HTML liệu không được khuyến khích.

Tôi đồng ý với điều đó. Một vấn đề là nó sẽ gây ra vấn đề nếu một thẻ không được đóng hoặc mở. Ví dụ như tất cả các giải pháp đề cập ở đây sẽ thay đổi

Lorem Test dolor Test <strong>dolor</strong></a> eirmod 

để

Lorem Test dolor Test <strong>dolor</strong></a> eirmod 1234 dolores sea 1234 takimata 
Các vấn đề liên quan