Tiếng Việt

Văn bản & công cụ hàng ngày · Bộ công cụ văn bản

Tại sao ^ và $ chỉ khớp một lần: cờ biểu thức chính quy trong trình duyệt tìm và thay thế

· Cách thức hoạt động

regular-expressions find-and-replace text-cleanup

Danh sách nhiều dòng hiển thị một neo toàn văn bản và các ranh giới dòng mới rõ ràng được lặp lại
Hình minh họa vector ToolAcre gốc

Giải thích các cờ biểu thức chính quy JavaScript — chung, nhiều dòng và dotAll — và lý do tại sao hộp tìm và thay thế được biên dịch mà không có neo nhiều dòng ^ và $ cho toàn bộ văn bản, thay vào đó là các mẫu hoạt động.

Mẫu chỉ cố định dòng đầu tiên - điều gì sẽ xảy ra khi bạn mong đợi ^ có nghĩa là 'bắt đầu mỗi dòng'

Danh sách được dán có thể chứa cùng một tiền tố không mong muốn trên mỗi hàng, tuy nhiên việc tìm kiếm `^prefix` chỉ xóa tiền tố đó khỏi hàng đầu tiên. Kết quả đáng ngạc nhiên đến từ cấu hình mẫu chứ không phải từ dữ liệu không nhất quán. Trong ToolAcre, `^` xác định phần bắt đầu của văn bản hoàn chỉnh vì biểu thức chính quy được biên dịch mà không có chế độ nhiều dòng.

Điểm neo `$` phù hợp tuân theo quy tắc tương tự ở cạnh bên kia: nó xác định phần cuối của văn bản hoàn chỉnh chứ không phải mọi dòng kết thúc bên trong nó. Dấu ngắt dòng vẫn là một phần của dữ liệu đầu vào nhưng nó không trở thành một vị trí neo khác. Kiểm tra số lượng thay thế được báo cáo trước khi nhập danh sách đã được làm sạch; số lượng một sẽ bộc lộ sự không phù hợp ngay lập tức.

Cờ g — tại sao 'thay thế mọi trận đấu trong một lượt' lại phụ thuộc vào cờ chung được đặt

ToolAcre luôn xây dựng mẫu tìm kiếm của mình bằng cờ `g` toàn cầu. Lựa chọn đó yêu cầu JavaScript thu thập mọi kết quả trùng khớp thay vì dừng lại sau kết quả đầu tiên. Trước tiên, công cụ gọi `match` để xác định số lượng, sau đó chuyển cùng một mẫu chung cho `replace`, do đó, số được hiển thị và thẻ thay thế sử dụng một quy tắc khớp.

Kết hợp toàn cầu không thể tạo các vị trí mà mẫu không nhận ra. Với `^prefix`, chỉ có một phần đầu toàn văn đủ điều kiện, vì vậy `g` vẫn tìm thấy một kết quả phù hợp. Với một mẫu có thể xuất hiện trên nhiều hàng, `g` cho phép thay thế tất cả các lần xuất hiện. Tách các câu hỏi này khi gỡ lỗi: các điểm cố định quyết định nơi trận đấu có thể bắt đầu, trong khi chế độ chung quyết định xem việc tìm kiếm có tiếp tục hay không.

Cờ m - cách nhiều dòng thay đổi ^ và $ từ neo toàn văn bản thành neo dòng và tại sao công cụ này lại tắt nó

Cờ `m` nhiều dòng thay đổi cách diễn giải `^` và `$`, cho phép chúng nhận biết các vị trí xung quanh dấu kết thúc dòng cũng như ranh giới văn bản bên ngoài. ToolAcre không thêm cờ đó. Trình biên dịch của nó sử dụng `g` cho các tìm kiếm phân biệt chữ hoa chữ thường và `gi` khi xóa phân biệt chữ hoa chữ thường mà không có sự kiểm soát của người dùng đối với các cờ bổ sung.

Việc không sử dụng nhiều dòng sẽ giúp giao diện nhỏ nhưng điều đó có nghĩa là các mẫu được sao chép từ trình chỉnh sửa được định cấu hình bằng `gm` có thể hoạt động khác ở đây. Đừng cho rằng một biểu thức quen thuộc mang cờ của nó. JavaScript các chữ cái cờ được cung cấp khi RegExp được tạo và công cụ này từ chối cú pháp cờ nội tuyến không được hỗ trợ thay vì âm thầm bật chế độ khác.

Cờ s - tại sao một dấu chấm không khớp với dòng mới theo mặc định và cách khớp giữa các dòng mà không có nó

Dấu chấm trong công cụ này không khớp với dấu ngắt dòng vì trình biên dịch cũng bỏ qua cờ dotAll `s`. Mẫu như `BEGIN.*END` có thể khớp khi cả hai điểm đánh dấu nằm trên một dòng nhưng nó dừng ở ngắt dòng đầu tiên khi điểm đánh dấu trải dài trên nhiều hàng. Việc thêm chế độ chung không làm thay đổi những gì dấu chấm có thể tiêu thụ.

Khi thực sự cần phải khớp chéo dòng, hãy viết rõ ràng các ký tự được phép. Một lớp như `[\s\S]*?` có thể mở rộng khoảng trắng và không phải khoảng trắng trong khi vẫn miễn cưỡng, mặc dù trước tiên các mẫu rộng xứng đáng được thử nghiệm trên một mẫu nhỏ. Trình biên dịch phát hiện cú pháp không hợp lệ nhưng không bảo vệ tab khỏi một biểu thức đắt tiền có hành vi quay lui nghiêm trọng.

Khớp các dòng mới một cách rõ ràng - sử dụng \n trong mẫu để bắt đầu và kết thúc dòng đích khi không có nhiều dòng

Đối với những dòng bắt đầu lặp lại mà không có chế độ nhiều dòng, hãy khớp phần đầu của văn bản hoặc dòng mới: `(^|\n)prefix`. Phương án thay thế đầu tiên xử lý hàng đầu tiên và phương án thứ hai xử lý các hàng sau bằng cách sử dụng dòng mới trước đó của chúng. Dấu ngoặc đơn nắm bắt bất kỳ ranh giới nào phù hợp, tạo ra cách thay thế để giữ lại cấu trúc đã phân tách các dòng.

Kỹ thuật này giả định các dấu phân cách nguồn cấp dữ liệu trong mẫu. Thư viện văn bản nhận dạng CRLF, LF và CR đơn độc khi thực hiện các thao tác trên dòng chuyên dụng nhưng tìm và thay thế tìm kiếm trực tiếp chuỗi gốc. Nếu nội dung được dán sử dụng dạng kết thúc dòng khác, hãy chuẩn hóa nội dung đó trước hoặc điều chỉnh cách diễn đạt một cách có chủ ý; nếu không, các hàng sau có thể không bị ảnh hưởng ngay cả khi chúng trông giống hệt nhau trên màn hình.

Khớp các ranh giới dòng một cách rõ ràng với (^|\n) và giữ nguyên dấu phân cách đã chụp

Giả sử đầu vào là `ID: apple`, `ID: pear` và `ID: plum` trên các dòng riêng biệt. Bật Regex, tìm `(^|\n)ID: ` và thay thế bằng `$1`. Trên hàng đầu tiên, `$1` là vị trí bắt đầu trống; ở các hàng sau, đó là dòng mới được ghi lại. Các nhãn biến mất trong khi cả ba ranh giới hàng vẫn giữ nguyên.

Đọc số lượng thay thế trước khi chấp nhận kết quả. Ba hàng sẽ tạo ra ba sự thay thế trong ví dụ này. Nếu số đếm là một, hãy kiểm tra mẫu thực tế và phần cuối dòng thay vì lặp lại thao tác. Bạn có thể hoàn tác sau khi thay thế, do đó, một bản thử nghiệm nhỏ có thể xác nhận cả việc khớp và xây dựng lại trước khi cùng một biểu thức chạm vào danh sách nhập dài hơn.

Điều này không bao gồm những gì - các cờ u, i và y và chèn dòng mới vào phần thay thế, điều mà trường một dòng không thể thực hiện được

Việc triển khai cũng sử dụng `i` khi tắt phân biệt chữ hoa chữ thường nhưng không hiển thị các điều khiển cho `u`, `y`, `m` hoặc `s`. Bài viết này không chỉ định hành vi cho các chế độ không khả dụng đó ngoài việc giải thích các hiệu ứng multiline và dotAll bị thiếu cần thiết cho ví dụ. Các mẫu từ môi trường JavaScript khác phải được xem xét dựa trên các cờ ToolAcre thực sự được biên dịch.

Nguồn chứng minh rằng văn bản thay thế được chuyển tới JavaScript `String.replace`, do đó, các thay thế như `$1`, `$&` và `$$` vẫn giữ nguyên ý nghĩa JavaScript của chúng. Nó không thiết lập mọi tương tác do trường kết xuất cung cấp từ các tệp được sử dụng ở đây. Đặc biệt, việc chèn các dòng mới vật lý thông qua giao diện nên được kiểm tra thay vì chỉ suy luận từ bản phác thảo.

Các cờ khác và hành vi của trường thay thế nằm ngoài việc triển khai công cụ này

Coi cờ như một phần của biểu thức chính quy, ngay cả khi giao diện chỉ hiển thị phần thân mẫu. Trong ToolAcre, mọi tìm kiếm đều mang tính tổng thể, chế độ không phân biệt chữ hoa chữ thường tùy chọn sẽ thêm `i`, đồng thời không có nhiều dòng và dấu chấm. Những thông tin thực tế đó giải thích lý do tại sao việc thay thế tiếp tục diễn ra trong các kết quả khớp thông thường trong khi `^`, `$` và dấu chấm vẫn giữ nguyên các ràng buộc toàn văn bản và một dòng mặc định của chúng.

Đối với danh sách được dán có tiền tố, `(^|\n)prefix` với `$1` là giải pháp thực tế vì nó đặt tên cho ranh giới và giữ nguyên ranh giới đó. Bắt đầu với các hàng đại diện, xác nhận số lượng, kiểm tra cấu trúc dòng kết quả và chỉ sau đó xử lý toàn bộ tập dữ liệu. Quy trình đó biến một kết quả khớp khó hiểu thành một bước dọn dẹp có thể xem lại trước khi nhập.