2015-09-06 10 views

Trả lời

14

Trong JavaScript, đối tượng cụm từ thông dụng có trạng thái . Điều này quan trọng khi cờ g ("toàn cầu") được áp dụng cho chúng và đôi khi được áp dụng theo những cách kỳ lạ. Trạng thái này là chỉ mục nơi trận đấu xảy ra lần cuối, thuộc tính của thuộc tính regex là .lastIndex. Khi bạn gọi exec hoặc test trên cùng một đối tượng regex một lần nữa, nó sẽ chọn từ nơi nó bị tắt.

Điều đang xảy ra trong ví dụ của bạn là cuộc gọi thứ hai, nó sẽ bắt đầu từ lần cuối cùng, và vì vậy nó bắt đầu sau ký tự thứ 10 trong chuỗi   — và không tìm thấy kết quả phù hợp ở đó, vì không có văn bản nào cả (và ngay cả khi có, xác nhận ^ sẽ không khớp).

Chúng ta có thể nhìn thấy những gì đang xảy ra nếu chúng ta nhìn vào lastIndex tài sản:

var reg = new RegExp("^19[-\\d]*","g"); 
 
snippet.log("Before first test: " + reg.lastIndex); 
 
snippet.log(reg.test('1973-02-01')); //return true 
 
snippet.log("Before second test: " + reg.lastIndex); 
 
snippet.log(reg.test('1973-01-01')); //return false 
 
snippet.log("After second test: " + reg.lastIndex);
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --> 
 
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

Nếu không có sự g cờ, đối tượng regex không giữ bất cứ tiểu bang và bắt đầu từ đầu chuỗi mỗi lần:

var reg = new RegExp("^19[-\\d]*"); 
 
snippet.log("Before first test: " + reg.lastIndex); 
 
snippet.log(reg.test('1973-02-01')); //return true 
 
snippet.log("Before second test: " + reg.lastIndex); 
 
snippet.log(reg.test('1973-01-01')); //return false 
 
snippet.log("After second test: " + reg.lastIndex);
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --> 
 
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>


Side lưu ý: Nói chung, tốt nhất là để viết biểu thức thông thường trong JvaScript sử dụng literals regex thay vì sử dụng RegExp constructor và chuỗi. Trong trường hợp của bạn, đó sẽ là

var reg = /^19[-\d]*/g; 
// or without the g flag: 
var reg = /^19[-\d]*/; 

Side lưu ý 2: Nó không có ý nghĩa nhiều để xác định một biểu thức chính quy với một ^ hay $ neo các g cờ trừ khi bạn cũng sử dụng cờ m (nhiều dòng) để thay đổi ý nghĩa của các neo đó. không có m, chúng có nghĩa là "bắt đầu (^) hoặc kết thúc ($) đầu vào". Với cờ m, chúng có nghĩa là "bắt đầu (^) hoặc kết thúc ($) của dòng".

+4

Câu trả lời tốt và phức tạp (như thường lệ :-). Tôi sẽ thêm một lưu ý (3) làm rõ rằng cùng một đầu ra chính xác sẽ được tạo ra nếu 2 chuỗi ngày giống nhau (ví dụ, '1973-02-01'' trong cả hai cuộc gọi) – Amit

+0

cảm ơn vì giải thích của bạn, nó giúp rất nhiều. Và về phía lưu ý của bạn, tôi nghĩ rằng đó là 'var reg = [^ 19 [- \ d] */g;' –

+0

@ChopperLee: Vâng, tôi quên xóa dấu gạch chéo ngược. :-) Tôi nhớ khi tôi bắt đầu * gõ ghi chú bên, nhưng ... (Cố định ngay) –

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