Tại sao các biểu thức chính quy được tạo bằng trình tạo regex sử dụng cú pháp khác với các biểu thức chính quy tương tác?


26

Vì vậy, bằng cách sử dụng trình tạo biểu thức chính quy (trình xây dựng lại Mx), tìm các dòng kết thúc bằng \ mất "\ $", trong khi tìm kiếm và thay thế bằng regex, chỉ mất "\ $". Tôi đã mong đợi trình xây dựng regex xây dựng các biểu thức có thể sử dụng trực tiếp, vậy điều gì giải thích cho sự khác biệt này?


6
Nó xây dựng các biểu thức có thể sử dụng trực tiếp trong mã.
abo-abo

1
@ abo-abo Đó là câu trả lời tôi đang tìm kiếm, tôi đã không nhận ra rằng có một sự khác biệt giữa những gì có thể sử dụng được trong mã và những gì có thể sử dụng được trong ui. Có vẻ như trực quan rằng người xây dựng lại sử dụng cú pháp mã và hướng dẫn không nói, nhưng điều đó giải thích sự khác biệt.
dùng2699

2
Để làm cho trình xây dựng regex trở nên hữu ích hơn cho việc soạn thảo các tìm kiếm tương tác, hãy xem trang wiki ReBuilder emacs , đặc biệt là reb-query-replaceđịnh nghĩa hàm.
dfeich

Câu trả lời:


29

Thực tế, có bốn re-buildertùy chọn cú pháp khác nhau và bạn có thể chuyển đổi giữa chúng vớiC-cTAB

Hai là dành cho trình biên dịch regrec dạng sexp rxsregex(nhưng vì trước đây là toàn diện hơn và gần như hoàn toàn tương thích cú pháp, bạn thực sự có thể bỏ qua sregex trừ khi bạn tình cờ làm việc với mã cũ đã sử dụng nó).

Hai tùy chọn cú pháp khác là read(mặc định) và string(là cú pháp bạn sử dụng tương tác).

Các readcú pháp là cú pháp 'mã' - tức là công nhận bởi người đọc lisp - trong đó bạn nhập regexp theo cú pháp đọc cho chuỗi :

C-hig (elisp) Syntax for Strings RET

Các stringcú pháp (mà tôi đã luôn luôn được coi là một tên khó hiểu không cần thiết trong bối cảnh này) là cấu trúc của một chuỗi biểu thức chính quy mà đã được đọc , và do đó không có bất kỳ nhân vật thoát cần thiết khi viết chuỗi. Có thể nói, đây là cú pháp biểu thức chính quy thực tế , giống như bạn sử dụng khi Emacs nhắc bạn tương tác.

Nếu bạn muốn sử dụng cú pháp chuỗi theo mặc định, hãy thêm đoạn mã sau vào tệp init của bạn hoặc sử dụng M-x customize-option RET reb-re-syntax RET

(setq reb-re-syntax 'string)

Lưu ý rằng bạn có thể chuyển đổi qua lại giữa cú pháp đọc và chuỗi khi chỉnh sửa biểu thức chính quy, không mất dữ liệu. Bạn cũng có thể chuyển từ các hình thức sexp sang cú pháp đọc / chuỗi (một cách tự nhiên; biên dịch sexps thành chuỗi là những gì các thư viện dành cho), nhưng bạn không thể đi theo hướng khác và tạo ra một sexp từ một chuỗi. người xây dựng lại ghi nhớ sexp là gì, vì vậy bạn không bị mất hình thức đó khi thay đổi cú pháp; nhưng nó cũng không được cập nhật nếu bạn sửa đổi biểu thức chính quy theo một cú pháp khác và sau đó thay đổi lại. Nói tóm lại, nếu bạn đang xây dựng regrec dưới dạng sexp, hãy đảm bảo bạn chỉ chỉnh sửa nó trong khi sử dụng cú pháp đó.


Một vấn đề với sự rxhỗ trợ là nó thực sự sử dụng rx-to-stringhàm, nó không hoàn toàn giống với việc sử dụng rxmacro trong mã. rxchấp nhận một số lượng đối số biểu mẫu tùy ý và coi chúng là một chuỗi ngụ ý , trong khi rx-to-stringchỉ chấp nhận một hình thức duy nhất và bất kỳ chuỗi cấp cao nhất nào cũng phải được làm rõ ràng '(sequence ...)hoặc tương đương.

Nói tóm lại, khi bạn nhập một biểu mẫu '(...)trong trình xây dựng lại, nó được xử lý như là (rx-to-string '(...))và không(rx ...)

Ngoài ra, hãy lưu ý rằng một biểu mẫu không hợp lệ có thể khiến re-builderngừng cập nhật động các kết quả khớp trong bộ đệm được liên kết, ngay cả sau khi biểu mẫu được xác thực lại. Các C-cC-uràng buộc cho reb-force-updatelà hữu ích để giải quyết các tình huống này.


Theo mặc định, dòng chế độ hiển thị "RE Builder" khi sử dụng readhoặc stringcú pháp và "RE Builder Lisp" khi sử dụng rxhoặc sregexcú pháp, nhưng có vẻ hữu ích hơn nhiều khi xác định cú pháp cụ thể được sử dụng (đặc biệt là để phân biệt giữa readstring).

Nếu bạn cài đặt delightgói từ GNU ELPA, bạn có thể sử dụng cách sau để thêm chỉ báo cú pháp vào dòng chế độ.

(let ((name '("Regexp[" (:eval (symbol-name reb-re-syntax)) "]")))
  (delight `((reb-mode ,name :major)
             (reb-lisp-mode ,name :major))))

Điều này thay đổi tên chế độ thành "Regapi [read]" theo readcú pháp và tương tự cho các chế độ khác.

Hoặc để bao gồm một gợi ý cho rxvs rx-to-stringgotcha được mô tả ở trên, hãy đặt dòng chế độ nói "Regapi [rx-to-string]" khi sử dụng rxcú pháp:

(let ((name '("Regexp["
              (:eval (symbol-name (if (eq reb-re-syntax 'rx)
                                      'rx-to-string
                                    reb-re-syntax)))
              "]")))
  (delight `((reb-mode ,name :major)
             (reb-lisp-mode ,name :major))))
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.