Mengapa ekspresi reguler yang dibuat dengan pembuat regex menggunakan sintaksis yang berbeda dari ekspresi reguler interaktif?

26

Jadi, menggunakan pembangun ekspresi reguler (Mx re-builder), menemukan baris yang diakhiri dengan \ membutuhkan "\\ $", sementara dalam mencari dan mengganti dengan regex, hanya dibutuhkan "\ $". Saya akan mengharapkan pembuat regex untuk membangun ekspresi yang dapat digunakan secara langsung, jadi apa yang menyebabkan perbedaan ini?

pengguna2699
sumber
6
Itu membangun ekspresi langsung dapat digunakan dalam kode.
abo-abo
1
@ abo-abo Itulah jawaban yang saya cari, saya tidak menyadari bahwa ada perbedaan antara apa yang dapat digunakan dalam kode dan apa yang dapat digunakan dalam ui. Tampaknya kontra intuitif bahwa pembangun ulang menggunakan sintaksis kode, dan manual tidak mengatakannya, tetapi itu menjelaskan perbedaannya.
user2699
2
Untuk membuat pembuat regex lebih berguna untuk menyusun pencarian interaktif, lihat halaman wiki ReBuilder emacs , terutama reb-query-replacedefinisi fungsi.
dfeich

Jawaban:

29

Sebenarnya ada empat re-builderopsi sintaks yang berbeda , dan Anda dapat beralih di antaranyaC-cTAB

Dua adalah untuk kompiler regexp sexp-form rxdan sregex(tetapi karena yang pertama lebih komprehensif dan hampir seluruhnya kompatibel dengan sintaks, Anda benar-benar dapat mengabaikan sregex kecuali Anda kebetulan bekerja dengan kode lama yang menggunakannya).

Dua opsi sintaks lainnya adalah read(default) dan string(yang merupakan sintaks yang Anda gunakan secara interaktif).

The readsintaks adalah 'kode' sintaks - yaitu seperti yang diakui oleh cadel pembaca - di mana Anda memasukkan regexp sesuai sintaks membaca untuk string :

C-hig (elisp) Syntax for Strings RET

The stringsintaks (yang saya selalu dianggap sebagai nama tidak perlu membingungkan dalam konteks ini) adalah sintaks dari string ekspresi reguler yang telah dibaca , dan yang karenanya tidak memiliki karakter melarikan diri diperlukan saat menulis string. Artinya, ini adalah sintaks ekspresi reguler aktual , sama seperti yang Anda gunakan saat Emacs meminta Anda secara interaktif.

Jika Anda ingin menggunakan sintaks string secara default, tambahkan berikut ini ke file init Anda, atau gunakan M-x customize-option RET reb-re-syntax RET

(setq reb-re-syntax 'string)

Perhatikan bahwa Anda dapat beralih antara sintaks baca dan string saat mengedit regexp, tanpa kehilangan data. Anda juga dapat beralih dari bentuk sexp ke membaca / sintaksis string (secara alami; kompilasi sexps menjadi string untuk apa perpustakaan itu), tetapi Anda tidak bisa pergi ke arah lain dan menghasilkan sexp dari string. re-builder mengingat apa itu sexp, jadi Anda tidak kehilangan formulir itu saat Anda mengubah sintaks; tetapi juga tidak bisa diperbarui jika Anda memodifikasi regexp dalam sintaks yang berbeda dan kemudian mengubahnya kembali. Singkatnya, jika Anda membangun regexp sebagai sexp, pastikan Anda hanya mengeditnya saat menggunakan sintaks itu.


Gotcha dengan rxdukungannya adalah bahwa itu sebenarnya menggunakan rx-to-stringfungsi, yang tidak cukup identik dengan menggunakan rxmakro dalam kode. rxmenerima sejumlah argumen bentuk yang sewenang-wenang dan memperlakukannya sebagai urutan yang tersirat , sedangkan rx-to-stringhanya menerima bentuk tunggal, dan urutan tingkat atas apa pun harus dibuat eksplisit dengan '(sequence ...)atau setara.

Singkatnya, ketika Anda memasukkan formulir '(...)di pembangun ulang, itu diproses sebagai (rx-to-string '(...))dan tidak(rx ...)

Perhatikan juga bahwa formulir yang tidak valid dapat menyebabkan re-builderberhenti memperbarui secara dinamis kecocokan dalam buffer terkait, bahkan setelah formulir dibuat valid lagi. The C-cC-uuntuk mengikat reb-force-updateberguna untuk menyelesaikan situasi ini.


Secara default, baris mode menampilkan "RE Builder" saat menggunakan readatau stringsintaks, dan "RE Builder Lisp" saat menggunakan rxatau sregexsintaks, tetapi tampaknya jauh lebih berguna untuk mengidentifikasi sintaks tertentu yang digunakan (terutama untuk membedakan antara readdan string).

Jika Anda menginstal delightpaket dari GNU ELPA, Anda dapat menggunakan yang berikut ini untuk menambahkan indikator sintaks ke baris mode.

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

Ini mengubah nama mode menjadi "Regexp [baca]" dalam readsintaks, dan juga untuk yang lain.

Atau untuk menyertakan petunjuk untuk rxvs rx-to-stringgotcha yang dijelaskan di atas, buat baris mode mengatakan "Regexp [rx-to-string]" saat menggunakan rxsintaks:

(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))))
phils
sumber