2009-05-04 29 views
5

Tôi đã điều tra vấn đề này mà dường như càng tồi tệ thì càng đào sâu hơn.biểu thức chính quy trong phân tách chuỗi javascript, vấn đề tương thích với trình duyệt

tôi bắt đầu ngây thơ đủ cố gắng sử dụng biểu thức này để tách một chuỗi vào 'BR' HTML tags:

T = captions.innerHTML.split(/<br.*?>/g); 

này hoạt động ở mọi trình duyệt (FF, Safari, Chrome), ngoại trừ IE7 và IE8 với ví dụ văn bản đầu vào như thế này:

is invariably subjective. <br /> 
The less frequently used warnings (Probably/Possibly) <br /> 

Xin lưu ý rằng văn bản mẫu có dấu cách trước '/' và đứng trước dòng mới.

Cả hai điều sau đây sẽ phù hợp với tất cả các thẻ HTML trong tất cả các trình duyệt:

T = captions.innerHTML.split(/<.*?>/g); 
T = captions.innerHTML.split(/<.+?>/g); 

Tuy nhiên, đáng ngạc nhiên (cho tôi ít nhất), này không làm việc trong FF và Chrome:

T = captions.innerHTML.split(/<br.+?>/g); 

Edit:

này (đề nghị nhiều lần trong các câu trả lời dưới đây,) không hoạt động trên IE 7 hoặc 8:

012.
T = captions.innerHTML.split(/<br[^>]*>/g); 

(Nó đã làm việc trên Chrome và FF.)

Câu hỏi của tôi là: không ai biết một biểu thức mà làm việc trong tất cả các trình duyệt hiện nay để phù hợp với thẻ 'BR' ở trên (nhưng không phải thẻ HTML khác) . Và bất kỳ ai cũng có thể xác nhận rằng ví dụ cuối cùng ở trên phải là một kết hợp hợp lệ vì hai ký tự có mặt trong văn bản mẫu trước '>'.

PS - loại tài liệu của tôi là HTML chuyển tiếp.

Edit:

Tôi nghĩ rằng tôi có bằng chứng này là cụ thể cho String.split() hành vi trên IE, và không regex nói chung. Bạn phải sử dụng split() để xem vấn đề này. Tôi cũng đã tìm thấy một ma trận thử nghiệm cho thấy tỷ lệ thất bại khoảng 30% đối với các trường hợp thử nghiệm split() khi tôi chạy nó trên IE. Các cuộc thử nghiệm tương tự thông qua 100% trên Chrome FF và:

http://stevenlevithan.com/demo/split.cfm

Cho đến nay, tôi vẫn chưa tìm ra giải pháp cho IE, và thư viện được cung cấp bởi tác giả của rằng ma trận kiểm tra không khắc phục được trường hợp này.

+0

PPS - Tôi hiện không thử nghiệm IE6 hoặc Opera, nhưng vui lòng thảo luận các vấn đề này nếu có liên quan. –

Trả lời

15

Lý do mã của bạn không hoạt động là do IE phân tích cú pháp HTML và làm cho các thẻ chữ hoa khi bạn đọc nó thông qua innerHTML. Ví dụ, nếu bạn có HTML như thế này:

<div id='box'> 
Hello<br> 
World 
</div> 

Và sau đó bạn sử dụng Javascript này (trong IE):

alert(document.getElementById('box').innerHTML); 

Bạn sẽ nhận được một hộp cảnh báo với điều này:

Hello<BR>World 

Lưu ý rằng <BR> bây giờ là chữ hoa. Để khắc phục điều này, chỉ cần thêm cờ i ngoài cờ g để làm cho regex trở nên phân biệt chữ hoa chữ thường và nó sẽ hoạt động như bạn mong đợi.

+0

Vâng, bạn hoàn toàn đúng. Một triệu cảm ơn, và bây giờ tôi biết một cái gì đó mới về innerHTML trên IE. –

6

Hãy thử điều này một:

/<br[^>]*>/gi 
+1

Tôi khuyên/gi vì bạn không bao giờ biết cách ai đó sẽ phân biệt thẻ của họ –

+0

Tính năng này hoạt động trong Chrome và FF và không hoạt động trong IE. Tôi đang đưa +1 vì nó * nên * hoạt động. –

+0

Btw, như tôi bây giờ nhận ra nó không thất bại khi sử dụng chính xác như bạn cung cấp ở đây. Tôi bỏ qua cờ 'i' vì tôi đang làm việc với một nguồn trường hợp thấp hơn đã biết. bài học kinh nghiệm: các thẻ IE up-in trong innerHTML. –

0

Regexes về cơ bản dở phân tích cú pháp HTML (xem Can you provide some examples of why it is hard to parse XML and HTML with a regex? cho lý do tại sao). Những gì bạn cần là một trình phân tích cú pháp HTML. Xem Can you provide an example of parsing HTML with your favorite parser? để biết các ví dụ sử dụng nhiều trình phân tích cú pháp khác nhau.

Đặc biệt bạn có thể quan tâm đến số JavaScript+DOM answer.

+2

Vâng, tôi không có ý định thực hiện một trình phân tích cú pháp HTML đầy đủ và đây không phải là môi trường jQuery. Xin lưu ý, không có vấn đề gì với việc regex xử lý vấn đề này, nhưng vấn đề tương thích với trình duyệt trong IE 7 và 8. (Mặc dù ví dụ thất bại trong FF cũng khiến tôi khó hiểu.) –

+1

"Regexes về cơ bản không tốt khi phân tích cú pháp HTML" - không nếu bạn biết đầu vào sẽ trông như thế nào. – nickf

+0

@Walt Gordon Jones Nó không phải là vấn đề bạn dự định làm hay không, regexes không thể xử lý HTML, nó không phải là những gì họ giỏi, ít nhất hãy xem nó với một trình phân tích cú pháp, bạn luôn có thể sử dụng DOM. –

1

Thay vì

/<br.*?>/ 

bạn có thể thử

/<br[^>]*>/ 

ví dụ phù hợp với "<br", tiếp theo là bất kỳ nhân vật khác hơn '>', tiếp theo là '>'.

+0

Cảm ơn, vẫn không thành công trong IE. –

0

Vâng, tiếc là tôi không có một loạt các trình duyệt tại nơi làm việc (chỉ trình duyệt IE - tiếng thở dài) nhưng ngay lập tức tôi có thể nhìn thấy một cách để tối ưu hóa regex của bạn:

T = captions.innerHTML.split(/<br[^>]*?>/g); 

Nhân vật inline định nghĩa lớp [^>] chỉ thị biểu thức khớp với bất kỳ ký tự nào EXCEPT dấu lớn hơn. Bạn cũng có thể muốn làm cho nó không phân biệt chữ hoa chữ thường (pass gi ở cuối không chỉ g).

+0

Trong một số công cụ biểu thức chính quy, *? toán tử cho biết kết hợp không tham lam, trong đó /.*?>/ sẽ khớp với bất kỳ ký tự nào tới điểm * đầu tiên * mà văn bản sau khớp với. Nếu không có?, /.*>/ khớp với điểm * cuối cùng * nơi văn bản sau khớp với nhau. –

+0

Có, muốn trận đấu đầu tiên (rõ ràng), nhưng [^>] trông giống như một cách thông minh để buộc trận đấu đầu tiên vì đó là cách duy nhất để thỏa mãn điều kiện. Bất kể, ngay cả các biến thể mà nên tham lam không phù hợp với tất cả dưới IE. –

0

Tested trong Firefox 3 & IE7:

/<br.*?>/gi 

Hãy thử nó cho mình ở đây: http://jsbin.com/ofoke

var input = "one <br/>\n" 
      + "two <br />\n" 
      + "three <br>\n" 
; 

alert(input.replace(/<br.*?>/gi, '')); 
+0

Tôi tin rằng tôi đã xác định vấn đề cụ thể với String.split trên IE. (Ví dụ của bạn sử dụng String thay thế.) Hãy xem ma trận trường hợp thử nghiệm này để tách(): http://stevenlevithan.com/demo/split.cfm IE không thành công khoảng 30% các trường hợp. FF và Chrome vượt qua ma trận này 100%. –

+0

sau đó bạn có thể thử làm một cái gì đó như thay thế bằng một regex, để thay thế các thẻ
bằng "|| BR ||" và sau đó sử dụng một phi regex bình thường để phân chia nó? input.replace (/ /gi, '|| BR ||'). Split ("|| BR ||"); Điều đó có hiệu quả không? – nickf

0

< \ s BR \ s /? \ S *>

trận

<br>, <br />, <br>,<br/> 

Tôi đã thử nghiệm here trong IE.6. Nếu tháng ba là Ok, js chắc chắn có thể chia nó theo regexp.

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