2009-09-17 30 views
5

Tôi đang cố trả lại nội dung của bất kỳ thẻ nào trong phần nội dung văn bản. Tôi hiện đang sử dụng biểu thức sau, nhưng nó chỉ ghi lại nội dung của thẻ đầu tiên và bỏ qua bất kỳ nội dung nào khác sau đó.Cách lấy regex để khớp với nhiều thẻ tập lệnh?

Dưới đây là một mẫu của các html:

<script type="text/javascript"> 
     alert('1'); 
    </script> 

    <div>Test</div> 

    <script type="text/javascript"> 
     alert('2'); 
    </script> 

regex của tôi trông như thế này:

//scripttext contains the sample 
re = /<script\b[^>]*>([\s\S]*?)<\/script>/gm; 
var scripts = re.exec(scripttext); 

Khi tôi chạy trên IE6, nó sẽ trả về 2 trận đấu. Thẻ đầu tiên chứa thẻ đầy đủ, cảnh báo chứa thứ 2 ('1').

Khi tôi chạy nó trên http://www.pagecolumn.com/tool/regtest.htm, nó cung cấp cho tôi 2 kết quả, mỗi thẻ chỉ chứa các thẻ tập lệnh.

+0

Bạn có thực sự viết regex trong javascript? Bạn có thể bao gồm mã phù hợp không. – cdm9002

+0

Sử dụng RegexBuddy 3.2.1, tính năng này hoạt động tốt. Nó nắm bắt nội dung của cả hai thẻ. – Phoexo

+0

Tôi đang sử dụng/gm. Tôi sửa đổi hơi regexp một chút. Bây giờ nó trở về 2 kết quả, mỗi kết quả có chứa một thẻ script nhưng nó bao gồm html. \t ] *> ([\ s \ S] *?) <\/script>/gm Làm cách nào để chỉ trả lại nội dung? – Geuis

Trả lời

28

Các "vấn đề" ở đây là như thế nào exec công trình. Nó chỉ khớp với lần xuất hiện đầu tiên, nhưng lưu trữ chỉ mục hiện tại (tức là vị trí dấu mũ) trong thuộc tính lastIndex của một regex. Để nhận được tất cả các trận đấu chỉ cần áp dụng regex để chuỗi cho đến khi nó không phù hợp (đây là một cách khá phổ biến để làm điều đó):

var scripttext = ' <script type="text/javascript">\nalert(\'1\');\n</script>\n\n<div>Test</div>\n\n<script type="text/javascript">\nalert(\'2\');\n</script>'; 

var re = /<script\b[^>]*>([\s\S]*?)<\/script>/gm; 

var match; 
while (match = re.exec(scripttext)) { 
    // full match is in match[0], whereas captured groups are in ...[1], ...[2], etc. 
    console.log(match[1]); 
} 
+3

Điều này giải quyết được vấn đề. – asdacap

+0

'. Chết tiệt, hư hỏng lần nữa! '); ' – Svante

+0

@Svante thì sao? :) – kangax

2

Hãy thử sử dụng lá cờ toàn cầu:

document.body.innerHTML.match(/<script.*?>([\s\S]*?)<\/script>/gmi) 

Edit: thêm nhiều dòng và trường hợp cờ không nhạy cảm (vì lý do rõ ràng).

+0

hoặc, nếu bạn đang sử dụng chức năng regex, hãy đảm bảo nó được định cấu hình để bắt tất cả các kết quả phù hợp. Một số người trong số họ yêu cầu nhiều cuộc gọi hoặc tham số bổ sung hoặc chức năng khác được gọi. – TheJacobTaylor

+0

@TheJacobTaylor Có vẻ như mơ hồ. Chức năng regex nào bạn đang đề cập đến ngoài 'RegExp' mới? –

+0

@Justin Johnson Bình luận của tôi phần nào được điều khiển bởi những câu hỏi ở trên về ngôn ngữ mà regex đang ở. Vì tôi không chắc chắn, và họ đã nhận được kết quả, tôi nghĩ họ có thể bị ảnh hưởng bởi việc gọi sai chức năng. Trong PHP, ví dụ, preg_match và preg_match_all sẽ trả về kết quả đầu tiên hoặc tất cả các kết quả phù hợp. – TheJacobTaylor

0

Nhóm đầu tiên chứa nội dung của các thẻ.

Chỉnh sửa: Bạn không phải bao quanh regex-satement với dấu ngoặc kép? Giống như:

re = "/<script\b[^>]*>([\s\S]*?)<\/script>/gm"; 
+0

Không, bạn không biết. Trong javascript, /.../ biểu thị một biểu thức chính quy. Bạn có thể xây dựng nó như là một chuỗi nếu bạn muốn, nhưng sau đó bạn phải rõ ràng hơn trong xây dựng của nó. Ví dụ: '/ ] *> ([\ s \ S] *?) <\/script>/g' tương đương với 'mới RegExp (" ] *> ([\ s \ S] *?) <\/script> "," g ") ' –

0

Trong .Net, có phương thức submatch, trong PHP, preg_match_all, sẽ giúp bạn giải quyết vấn đề. Trong Javascript không có phương pháp như vậy. Nhưng bạn có thể tự làm.

thử nghiệm trong http://www.pagecolumn.com/tool/regtest.htm

Chọn $ 1elements phương pháp sẽ trở lại những gì bạn muốn

3

Không sử dụng biểu thức thông thường để phân tích cú pháp HTML. HTML không phải là ngôn ngữ thông thường. Sử dụng sức mạnh của DOM. Điều này là dễ dàng hơn nhiều, bởi vì nó là công cụ thích hợp.

var scripts = document.getElementsByTagName('script'); 
+0

Luôn có các lý do muốn phân tích cú pháp dom từ chuỗi. IE8 thổi đi các thẻ script nếu bạn cố gắng sử dụng innerHTML, ví dụ. Nếu tôi đang xây dựng một ứng dụng bằng cách sử dụng các widget và các mẫu html được mô đun hóa, điều này sẽ trở thành một vấn đề. – user2867288

+1

Đôi khi bạn cần phải khử trùng một chuỗi HTML trước khi biến nó thành một DOM. –

+0

@YuvalA .: hai khả năng: 1. Đó là HTML không hợp lệ; thì bạn cần một "trình phân tích cú pháp của thẻ". 2. Đó là HTML hợp lệ; thì bạn cần một trình phân tích cú pháp HTML. Trong mọi trường hợp, bạn có thể sử dụng cú pháp truy vấn đơn giản sau khi phân tích cú pháp. – Svante

0

thử này

for each(var x in document.getElementsByTagName('script'); 
    if (x && x.innerHTML){ 
      var yourRegex = /http:\/\/\.*\.com/g; 
      var matches = yourRegex.exec(x.innerHTML); 
      if (matches){ 
      your code 
}} 
+0

Đã có một câu trả lời được chấp nhận cho câu hỏi này hoàn thành những gì cần thiết. –

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