2009-06-05 28 views
16

Tôi đang gặp một số khó khăn với Regex cụ thể mà tôi đang cố gắng sử dụng. Tôi đang tìm kiếm mọi lần xuất hiện của một chuỗi (cho mục đích của mình, tôi sẽ nói đó là "mystring") trong tài liệu, EXCEPT vị trí của nó trong thẻ, ví dụ:Sử dụng regex để tìm chuỗi cụ thể không có trong thẻ html

<a href="_mystring_"> 

nên không phù hợp, nhưng

<a href="someotherstring">_mystring_</a> 

nên phù hợp, vì nó không có trong thẻ (bên trong có nghĩa là "bên trong < và> đánh dấu") Tôi đang sử dụng chức năng regex NET cho này cũng.

+0

làm bạn có ý nghĩa ví dụ thứ hai của bạn nên * không * phù hợp? –

+5

[Chèn bắt buộc "không sử dụng regexes để phân tích cú pháp HTML" ở đây] –

+1

robbotic: không, nó phải khớp. Nó không nằm trong các mốc đánh dấu < and >. Tôi cần phải thay thế trên _mystring_ nhưng không phải khi nó là một phần của thẻ vì nó nằm trong ví dụ trên cùng. Ngoài ra, tải tệp này vào XDocument hoặc bất kỳ thứ gì không thực sự khả thi trong tình huống của tôi. – Sukasa

Trả lời

17

này nên làm điều đó:

(?<!<[^>]*)_mystring_ 

Nó sử dụng một cái nhìn tiêu cực đằng sau để kiểm tra xem chuỗi phù hợp không có một < trước đó mà không có một tương ứng>

+0

Mặc dù Tôi cần thêm một vài quy tắc bổ sung cho lookbehind và như vậy cho các nhu cầu cụ thể của tôi, đây là những gì có những thứ làm việc cho tôi. Cảm ơn bạn! – Sukasa

+1

Wow, đó là một regex đẹp! @ Sukasa, bạn có thể đăng bài cuối cùng mà bạn đã đưa ra không? – travis

+1

Không hoạt động với PHP mặc dù –

0

Tại sao lại sử dụng regex?

Đối với xhtml, tải nó vào XDocument/XmlDocument; cho (non-x) html Gói Agility Html có vẻ là một lựa chọn hợp lý hơn ...

Dù bằng cách nào, sẽ phân tích cú pháp html thành DOM để bạn có thể lặp qua các nút và kiểm tra chúng.

0

Tìm kiếm biểu thức chính quy thường không phải là một ý tưởng hay trong XML. Quá dễ dàng để gặp sự cố với các biểu thức tìm kiếm phù hợp với nhiều hoặc quá ít. Nó cũng gần như không thể xây dựng một regex có thể xác định chính xác và xử lý các phần CDATA, hướng dẫn xử lý (PI), và các chuỗi thoát mà XML cho phép.

Trừ khi bạn có toàn quyền kiểm soát nội dung XML bạn đang nhận và có thể đảm bảo nó sẽ không bao gồm các cấu trúc như vậy (và sẽ không thay đổi) tôi khuyên bạn nên sử dụng một trình phân tích cú pháp XML nào đó (XDocument hoặc XmlDocument in .net, chẳng hạn).

Có nói rằng, nếu bạn vẫn còn ý định sử dụng regex làm cơ chế tìm kiếm của bạn, một cái gì đó như sau sẽ làm việc bằng cách sử dụng lớp RegEx trong .NET. Bạn có thể muốn test it out với một số trường hợp thử nghiệm của riêng bạn tại một trang web như Regexlib. Bạn cũng có thể tìm kiếm danh mục biểu thức chính quy của họ để tìm thứ gì đó phù hợp với nhu cầu của bạn.

[>]. (_mystring_). [<]

0

Bỏ qua đó là có thực sự cách khác, và rằng tôi không có chuyên môn regex thật, nhưng một điều mà nảy ra trong đầu tôi là:

  • tìm thấy tất cả các mystring s mà lÀ trong các thẻ đầu tiên - vì tôi không thể viết biểu thức để làm ngược lại :)
  • thay đổi những cái gì khác
  • sau đó thay thế tất cả các khác mystring (còn sót lại không thẻ) khi bạn cần
  • khôi phục bản gốc mystring s đó là trong các thẻ

Vì vậy, sử dụng bạn có thể tìm thấy những người được gắn thẻ. Thay thế chúng bằng chuỗi khác. Bạn có bình thường thay thế trên mystring s còn lại không.Thay thế chuỗi khác quay lại mystring

Thô nhưng hiệu quả .... có thể.

2

Một lựa chọn nhanh chóng và dơ bẩn là sử dụng chức năng thay thế regex với gọi lại để mã hóa nội dung của thẻ (mọi thứ giữa < và>), ví dụ như sử dụng base64, sau đó chạy tìm kiếm của bạn, sau đó chạy một cuộc gọi lại khác để giải mã nội dung thẻ của bạn.

này cũng có thể tiết kiệm rất nhiều đầu gãi khi bạn cần phải loại trừ thẻ cụ thể từ một tìm kiếm regex - đầu xáo trộn chúng và bọc chúng trong một dấu hiệu rằng sẽ không phù hợp với tìm kiếm của bạn, sau đó chạy tìm kiếm của bạn, sau đó deobfuscate bất cứ điều gì là trong các dấu hiệu.

7

Khi xử lý regex của bạn không hỗ trợ cái nhìn chiều dài thay đổi phía sau, cố gắng này:

(<.+?>[^<>]*?)(_mystring_)([^<>]*?<.+?>) 

Preserve chụp nhóm 1 và 3 và thay thế nhóm chụp 2:

Ví dụ, trong Eclipse, tìm:

(<.+?>[^<>]*?)(_mystring_)([^<>]*?<.+?>) 

và thay thế bằng:

$1_newString_$3 

(bộ vi xử lý regex khác có thể sử dụng cú pháp nhóm chụp khác nhau, chẳng hạn như \ 1)

+0

Đây là câu trả lời bạn cần sử dụng trong PHP, tôi thấy ... cuối cùng. –

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