ekspresi reguler untuk mencocokkan EOF

90

Saya memiliki beberapa data yang terlihat seperti ini

john, dave, chris
rick, sam, bob
joe, milt, paul

Saya menggunakan regex ini untuk mencocokkan nama

/(\w.+?)(\r\n|\n|,)/

yang berfungsi untuk sebagian besar tetapi file berakhir tiba-tiba setelah kata terakhir yang berarti nilai terakhir tidak diakhiri \r\n, \natau ,diakhiri dengan EOF. Apakah ada cara untuk mencocokkan EOF di regex sehingga saya bisa memasangnya di pengelompokan kedua?

Ryan
sumber
Apakah Anda mencoba menangkap semua nama dalam satu grup atau satu grup pengambilan per nama?
Andrew Hare
satu hal yang harus dilakukan saat mengalami masalah dengan ekspresi reguler adalah mencoba elemen pola Anda secara terpisah. jika Anda mengkhawatirkan token pada akhirnya, uji ekspresi Anda tanpa token tersebut.
akf
hanya ingin menambahkan besar situs pengujian regex: regexplanet.com/simple
Northpole
@Sinan - Saya setuju; digabung
Marc Gravell

Jawaban:

160

Jawaban atas pertanyaan ini \Zmembutuhkan waktu beberapa saat untuk memahaminya, tetapi berhasil sekarang. Perhatikan bahwa sebaliknya, \Amencocokkan awal dari seluruh string (sebagai lawan ^dan $mencocokkan awal dari satu baris).

Ryan
sumber
5
Perlu diketahui jika Anda mencari fonktionalitas seperti itu di netbeans untuk pencarian file proyek dibandingkan dengan pencarian dalam file , berikut ini akan berperilaku berbeda ... (\s*)\?>(\s*)\Z... dan setelah beberapa penggalian lagi di sini adalah apa yang akan bekerja pada folder proyek : (\s*)\?>(\s*)(\n*)(\W)\Z FYI: ini untuk mengganti semua tag php penutup dengan jeda baris di akhir file.
MediaVince
1
Ternyata \Ajuga bekerja di Visual Studio temukan dan ganti. Seperti biasa, gunakan hal-hal seperti itu dengan hati-hati tetapi itu menyelamatkan saya dari banyak kesalahan manual begitu saya senang itu benar-benar akan melakukan hal yang benar.
Steve Pettifer
Sementara saya menggunakan Scannerkelas Java untuk membaca seluruh file sekaligus; jika saya gunakan \Zsebagai pembatas, karakter baris baru di belakangnya dipangkas. Saat saya mengubah pembatas menjadi \z, karakter baris baru di belakangnya dipertahankan. Sepertinya jawaban Martin Dorey juga berlaku untuk Java.
mmdemirbas
24

EOF sebenarnya bukanlah sebuah karakter. Jika Anda memiliki string multi-baris, '$' akan cocok dengan akhir string serta akhir baris.

Di Perl dan rekan-rekannya, \Adan \Zmencocokkan awal dan akhir string, sama sekali mengabaikan jeda baris.

Ekstensi GNU untuk regex POSIX digunakan \`dan \'untuk hal yang sama.

paxdiablo
sumber
17

Dalam Visual Studio, Anda dapat menemukan EOF suka begitu: $(?![\r\n]). Ini berfungsi apakah akhiran baris Anda CR, CRLF, atau hanya LF.

Sebagai bonus, Anda dapat memastikan semua file kode Anda memiliki penanda baris baru akhir seperti:

               Find What: (?<![\r\n])$(?![\r\n])
            Replace With: \r\n
 Use Regular Expressions: checked
Look at these file types: *.cs, *.cshtml, *.js

Bagaimana ini bekerja:

Temukan ujung garis (kecocokan lebar-nol) yang tidak didahului oleh CR atau LF, dan juga tidak diikuti oleh CR atau LF. Beberapa pemikiran akan menunjukkan kepada Anda mengapa ini berhasil!

Perhatikan bahwa Anda harus Mengganti Dengan karakter akhir baris yang Anda inginkan, baik itu CR, LF, atau CRLF.

ErikE
sumber
Ada bug di Visual Studio 2019 di mana melakukan penggantian semua dengan ini dapat mengakibatkan dua baris baru ditambahkan ke akhir file. Saya pikir itu ada hubungannya dengan opsi auto-insert newline on save.
Stevoisiak
9

Bandingkan perilaku \ Z yang disarankan Ryan dengan \ z:

$ perl -kita $ corpus = "halo \ n"; $ corpus = ~ s / \ Z / dunia / g; cetak (": $ corpus: \ n") '
:Halo Dunia
dunia:
$ perl -kita $ corpus = "halo \ n"; $ corpus = ~ s / \ z / dunia / g; cetak (": $ corpus: \ n") '
:Halo
dunia:
$ 

perlre sez:

\ Z Cocok hanya di akhir string, atau sebelum baris baru di akhir
\ z Cocok hanya di akhir string

Terjemahan kasus uji ke dalam Ruby (1.8.7, 1.9.2) berlaku sama.

Martin Dorey
sumber
2

Apakah Anda benar-benar harus menangkap pemisah garis? Jika tidak, regex inilah yang Anda butuhkan:

/\w+/

Itu dengan asumsi semua substring yang ingin Anda cocokkan seluruhnya terdiri dari karakter kata, seperti dalam contoh Anda.

Alan Moore
sumber
2

Mungkin coba $ (EOL / EOF) daripada (\ r \ n | \ n)?

/\"(.+?)\".+?(\w.+?)$/
Marc Gravell
sumber
2

Baru-baru ini saya mencari sesuatu seperti ini, tetapi untuk JavaScript.

Menempatkan ini di sini, sehingga siapa pun yang memiliki masalah yang sama bisa mendapatkan keuntungan

var matchEndOfInput = /$(?![\r\n])/gm;

Pada dasarnya ini akan cocok dengan akhir baris, yang tidak diikuti oleh carriage return atau karakter baris baru. Intinya ini sama dengan \Ztetapi untuk JavaScript.

Zlatin Zlatev
sumber
1

Dengan asumsi Anda menggunakan pengubah yang tepat yang memaksa untuk memperlakukan string secara keseluruhan (bukan baris demi baris - dan jika \ n berfungsi untuk Anda, Anda sedang menggunakannya), cukup tambahkan alternatif lain - akhir string: (\ r \ n | \ n |, | $)

leafnode.dll
sumber
0

/(\w.+?)(\r\n|\n|,|$)/

kubus
sumber
5
Mungkin. Saya tidak ingat lagi :-)
kubus