!rm`.*$
Với một regex duy nhất, Retina chạy trong chế độ Match. Điều này thường chỉ in số lượng các trận đấu, nhưng với !chúng tôi định cấu hình nó để in các trận đấu thực tế thay thế (được phân tách bằng các đường dẫn).
Regex thực tế chỉ là .*$. .*khớp với bất kỳ dòng nào (có khả năng trống), bởi vì .có thể khớp với bất kỳ ký tự nào ngoại trừ các dòng. Tôi sẽ đến $trong một phút.
Làm thế nào để chúng tôi làm cho nó in các trận đấu ngược lại? Bằng cách sử dụng chế độ khớp từ phải sang trái của .NET, được kích hoạt bằng r. Điều này có nghĩa là công cụ regex bắt đầu ở cuối chuỗi khi tìm kiếm kết quả khớp và hoạt động ngược.
Cuối cùng, mlàm cho $khớp với kết thúc của một dòng thay vì kết thúc chuỗi. Tại sao chúng ta thậm chí cần điều đó? Vấn đề là .*tạo ra các trận đấu không liên quan. Hãy xem xét sự thay thế regex
s/a*/$0x/
áp dụng cho đầu vào baaababaa. Bạn sẽ nghĩ rằng điều này sẽ mang lại baaaxbaxbaax, nhưng nó thực sự mang lại cho bạn baaaxxbaxxbaaxx. Tại sao? Bởi vì sau khi khớp aaacon trỏ của động cơ nằm giữa avà b. Bây giờ nó không thể khớp với bất kỳ as nào nữa , nhưng a*cũng hài lòng với một chuỗi rỗng. Điều này có nghĩa, sau mỗi trận đấu bạn sẽ nhận được một trận đấu trống khác.
Chúng tôi không muốn điều đó ở đây, vì nó sẽ giới thiệu các dòng trống bổ sung, vì vậy chúng tôi loại bỏ các kết quả trùng khớp đó ( bắt đầu từ các dòng, do chế độ từ phải sang trái) bằng cách yêu cầu các kết quả khớp đó bao gồm phần cuối của dòng.
taclà một chút lạ khi nói đến nguồn cấp dữ liệu. Nó biến đổia\nb\n(trailfeed lineing) thànhb\na\nvàa\nb(không có trailfeed lineing) thànhba\n. Đây có phải là cách mã của chúng tôi phải hành xử?