Đây không phải là bất thường: .*
có thể khớp với bất kỳ thứ gì.
Bạn hỏi thay thế tất cả lần xuất hiện:
- sự xuất hiện đầu tiên thực hiện phù hợp với toàn bộ dây, động cơ regex do đó bắt đầu từ ngày kết thúc đầu vào cho trận đấu tới;
- nhưng
.*
cũng khớp với một chuỗi rỗng! Do đó, nó khớp với một chuỗi rỗng ở cuối đầu vào và thay thế bằng a
.
Thay vào đó, sử dụng .+
sẽ không hiển thị vấn đề này vì regex này không thể khớp với chuỗi trống (yêu cầu ít nhất một ký tự để khớp).
Hoặc, sử dụng .replaceFirst()
chỉ thay thế sự xuất hiện đầu tiên:
"test".replaceFirst(".*", "a")
^^^^^^^^^^^^
Bây giờ, tại sao .*
cư xử như nó làm và không phù hợp hơn hai lần (nó có thể về mặt lý thuyết) là một điều thú vị để xem xét . Xem bên dưới:
# Before first run
regex: |.*
input: |whatever
# After first run
regex: .*|
input: whatever|
#before second run
regex: |.*
input: whatever|
#after second run: since .* can match an empty string, it it satisfied...
regex: .*|
input: whatever|
# However, this means the regex engine matched an empty input.
# All regex engines, in this situation, will shift
# one character further in the input.
# So, before third run, the situation is:
regex: |.*
input: whatever<|ExhaustionOfInput>
# Nothing can ever match here: out
Lưu ý rằng, như @ A.H. ghi chú trong các chú thích, không phải tất cả các công cụ regex đều hoạt động theo cách này. Ví dụ, GNU sed
sẽ xem xét rằng nó đã cạn kiệt đầu vào sau trận đấu đầu tiên.
Đồng ý. Điều này cũng đúng với Perl. 'perl -le '$ x =" test "; $ x = ~ s /.*/ a/g; in $ x'' sản lượng "aa". –
@ChrisDolan: 'sed' chỉ tạo ra' a', nhưng tôi nghi ngờ một lỗi của nó. :-) –
@ A.H. có thực sự ... Tôi cần phải đọc "Mastering Regular Expressions" một lần nữa – fge