2009-03-03 32 views
8

Tôi đã viết một thử nghiệm Javascript RegExp để phát hiện định dạng chuỗi ngày, tôi thêm một "g" cờ thừa do nhầm lẫn và tìm thấy một cái gì đó thú vị.Thú vị thử nghiệm của Javascript RegExp

var s = "2009/03/10"; 
var regex=/^\d{4}[/]\d{2}[/]\d{2}$/g; 
alert(regex.test(s)); 
alert(regex.test(s)); 
alert(regex.test(s)); 
alert(regex.test(s)); 

Tôi nhận được 'true', sau đó là 'false', sau đó lại là 'false'.

Nếu tôi sử dụng vòng lặp để thực thi nó, tôi thấy điều thú vị hơn, tôi nhận được bốn "true" trong IE và Safari, và đúng, sai, đúng, sai trong FF, Chrome.

for (var i=0; i<4; i++) 
{ 
    var s = "2009/03/10"; 
    var regex=/^\d{4}[/]\d{2}[/]\d{2}$/g; 
    alert(regex.test(s)); 
} 

Có ai có ý tưởng giải thích lý do tại sao regex Javascript hoạt động như vậy và điều gì làm cho trình duyệt trả về các kết quả khác nhau? (liên quan đến khai báo biến và phạm vi cuộc sống?)

Trả lời

19

Khi bạn sử dụng cờ toàn cầu trên JS RegExp các phương pháp "thử nghiệm" và "exec" từng dừng ở kết quả đầu tiên nhưng giữ con trỏ đến nơi họ ngừng tìm kiếm chuỗi. Con trỏ đó có thể được kiểm tra trên thuộc tính lastIndex. Khi bạn gọi lại "test" hoặc "exec", nó bắt đầu tìm kiếm một trận đấu bắt đầu từ lastIndex.

Vì vậy, khi bạn kiểm tra RegExp trên một chuỗi khớp với toàn bộ chuỗi, lastIndex được đặt ở cuối chuỗi. Lần tiếp theo bạn thử nghiệm nó bắt đầu ở cuối chuỗi, trả về false và đặt lastIndex về 0.

MDC có decent explanation về hành vi này.

+0

Cảm ơn rất nhiều, giải thích của MDC rất rõ ràng. – Darkthread

+0

+1 cảm ơn sự giúp đỡ, thiết lập reg.lastIndex = 0 trước khi mỗi bài kiểm tra giải quyết được vấn đề của tôi. – bendewey

+0

Dường như bạn có thể đặt lastIndex = 0 trước mỗi bài kiểm tra nếu điều này gây ra sự cố trong vòng lặp chẳng hạn. – k0nG

0

Để tránh hành vi lạ này không sử dụng cờ toàn cục (g).

Mã này nên đầu ra: 'Đúng', 'True', 'True', 'True'

var s = "2009/03/10"; 
var regex=/^\d{4}[/]\d{2}[/]\d{2}$/i; 
alert(regex.test(s)); 
alert(regex.test(s)); 
alert(regex.test(s)); 
alert(regex.test(s)); 

Các toàn cầu (g) ​​phẳng thiết lập RegExp.lastIndex tài sản. Vì vậy, mỗi bài kiểm tra() sẽ bắt đầu khi điểm cuối cùng dừng lại.

Để biết thêm thông tin, hãy xem tài liệu về RegExp.lastIndex

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