Hanya mencocokkan kejadian pertama yang sejalan dengan Regex

42

Saya benar-benar baru untuk regex dan saya akan sangat menghargai bantuan apa pun.

Tugasnya sederhana. Saya memiliki file CSV dengan catatan yang berbunyi seperti ini:

12345,67890,12345,67890
12345,67890,12345,67890
12345,67890,12345,67890
12345,67890,12345,67890
12345,67890,12345,67890

Saya ingin mengganti koma pertama dengan spasi dan membiarkan koma lainnya tetap utuh, untuk setiap baris. Apakah ada ekspresi regex yang hanya cocok dengan koma pertama?

Saya mencoba ini: ^.....,. Ini cocok dengan koma, namun, itu juga cocok dengan seluruh panjang string sebelum koma, jadi jika saya mencoba untuk mengganti ini dengan spasi semua nomor juga dihapus.

cows_eat_hay
sumber
alat apa yang kamu gunakan? (sed, perl, awk, sesuatu yang lain?)
Mat
Textpad (Windows)
cows_eat_hay

Jawaban:

53

Pola yang cocok bisa jadi:

^([^,]+),

Itu berarti

^        starts with
[^,]     anything but a comma
+        repeated one or more times (use * (means zero or more) if the first field can be empty)
([^,]+)  remember that part
,        followed by a comma

Dalam misalnya perl, seluruh pertandingan dan penggantian akan terlihat seperti:

s/^([^,]+),/\1 /

Bagian pengganti hanya mengambil semua yang cocok dan menggantinya dengan blok pertama yang Anda ingat dan menambahkan spasi. Koma "dijatuhkan" karena tidak ada dalam kelompok penangkapan pertama.

Tikar
sumber
Luar biasa! Terima kasih Mat, itu bekerja dengan baik. Sebenarnya itu tidak bekerja di Textpad (saya pikir regex mereka terbatas), jadi saya akhirnya mengunduh PowerGrep, dan menggunakan pencarian dan ganti dengan ekspresi yang Anda berikan dan itu berfungsi dengan baik. Terima kasih juga atas penjelasannya yang bagus, ini membantu memahami apa yang sedang terjadi.
cows_eat_hay
7
s/,/ /

Ini, secara default (yaitu tanpa gopsi), hanya menggantikan kecocokan pertama.

Mork
sumber
1
Apakah ini sebenarnya Textpad search & replace syntax?
Daniel Beck
1
Ini adalah sintaks sed, perldan beberapa alat lainnya.
pabouk
3

Ini harus sesuai hanya nomor pertama dan koma: ^(\d{5}),. Jika Anda ingin melahap semua yang ada di baris, ubah regex menjadi ini:^(\d{5}),(.*)$

alex
sumber
Ini juga berhasil. Saya benar-benar menggunakan solusi Mat, tetapi saya juga menguji Anda dan itu berhasil. Terima kasih untuk bantuannya!
cows_eat_hay
Kenapa \d{5}& tidak [^,]*? Itu @ setidaknya akan lebih umum.
JustinCB
2

Solusi yang lebih elegan adalah menggunakan pencocokan malas:

s/^(.+?),/\1 /

yang akan mengelompokkan karakter dengan memindahkan dari awal string ( ^) ke akhir dengan satu karakter ( .+?) pada setiap langkah sampai menemukan tanda koma pertama. Semua grup ini bersama dengan kejadian koma pertama akan diganti oleh grup ( \1) dan karakter spasi.

ghost28147
sumber
Perhatikan bahwa ini tidak akan cocok dengan baris yang tidak mengandung koma (nilai tunggal pada satu baris). Mencocokkan apa pun * mungkin lebih baik dari yang satu +itus/^(.*?),/\1 /
Jeff Puckett
Anda juga bisa melakukannya s/^([^,]*),/\1 /, yang akan cocok dengan awal, apa pun yang bukan koma, lalu koma. Juga, tidakkah Anda tahu itu s//tidak mengubah apa pun yang tidak cocok?
JustinCB
1

TextPad selalu memiliki kemampuan untuk menggunakan notasi posix, tetapi Anda harus mengubah pengaturan di kotak dialog yang berbeda. Untuk menggunakan pengaturan default TextPad untuk ekspresi reguler, Anda harus "keluar" dari tanda kurung buka dan tutup:

Ganti spasi setelah kode pos 5 digit, di awal setiap baris

^\([0-9]+\)[ ]

Dengan tab

\1\t

Seperti di atas, ^ berarti awal baris

\ (adalah "tanda kurung lolos" dan ini menandai awal dari ekspresi pencarian pertama, yaitu, lima digit

[0-9] + berarti satu atau lebih digit (bukan hanya kode pos 5 digit)

\) adalah "tanda kurung lain" untuk menandai akhir dari ekspresi pencarian pertama

[] hanyalah karakter luar angkasa (Anda bisa meninggalkan tanda kurung, tetapi tidak ada yang bisa melihatnya di halaman web ini :-)

Dalam ekspresi pengganti

\ 1 adalah ekspresi pencarian pertama, bagian di antara tanda kurung di atas (satu atau lebih digit)

\ t adalah karakter tab

Jadi perintah cari dan ganti mencari satu atau lebih digit, diikuti oleh spasi. Kemudian itu menggantikan semua itu dengan kelompok digit yang sama diikuti oleh tab.

Saya tidak berpikir ada cara hanya untuk menemukan "ruang yang datang setelah 5 digit" sehingga Anda bisa mengganti ruang tanpa menyentuh digit. Anda harus menemukan 5 digit (string pertama) diikuti oleh spasi (string kedua). Kemudian, meskipun tampak berlebihan atau rumit, REPLACE string asli 5 digit dengan ITSELF, diikuti oleh tab (string kedua).

Semua orang yang tahu ini lupa bahwa pemula tidak tahu tentang ini. Itu sebabnya saya mengeja untuk Anda, teman saya.

Ed Poor Math Tutor dan pensiunan Programmer Komputer New York City

pengguna423655
sumber
0

Untuk mencocokkan hanya kemunculan pertama ekspresi regex, hapus semua bendera. Setiap ekspresi regex hadir dengan kemungkinan flag berikut dan biasanya default untuk menggunakan flag global yang akan cocok dengan lebih dari satu kemunculan:

  • / g = Dengan bendera ini pencarian mencari semua kecocokan, tanpa itu - hanya kecocokan pertama yang dikembalikan
  • / i = tidak sensitif huruf
  • / m = mode multi-line
  • / s = semua. untuk mencocokkan karakter baris baru \ n
  • / u = unicode
  • / y = mode lengket (cari di lokasi tertentu)
Michael Scarpace
sumber