Regex cara mencocokkan karakter opsional

147

Saya memiliki regex yang saya pikir berfungsi dengan benar sampai sekarang. Saya perlu mencocokkan pada karakter opsional. Mungkin ada di sana atau tidak.

Berikut ini dua string. String teratas dicocokkan sedangkan yang lebih rendah tidak. Tidak adanya satu huruf di string bawah adalah apa yang membuatnya gagal.

Saya ingin mendapatkan satu huruf setelah 5 digit awal jika ada dan jika tidak, terus dapatkan sisa string. Surat ini bisa A-Z.

Jika saya menghapus ([A-Z]{1}) +.*? +dari regex, itu akan cocok dengan semua yang saya butuhkan kecuali surat itu tetapi itu agak penting.

20000      K               Q511195DREWBT            E00078748521
30000                      K601220PLOPOH            Z00054878524

Berikut adalah regex yang saya gunakan.

/^([0-9]{5})+.*? ([A-Z]{1}) +.*? +([A-Z]{1})([0-9]{3})([0-9]{3})([A-Z]{3})([A-Z]{3}) +([A-Z])[0-9]{3}([0-9]{4})([0-9]{2})([0-9]{2})/
Jim
sumber

Jawaban:

246

Menggunakan

[A-Z]?

untuk membuat surat itu opsional. {1}berlebihan. (Tentu saja Anda juga bisa menulis [A-Z]{0,1}yang artinya sama, tapi memang untuk itulah ?.)

Anda dapat meningkatkan regex Anda menjadi

^([0-9]{5})+\s+([A-Z]?)\s+([A-Z])([0-9]{3})([0-9]{3})([A-Z]{3})([A-Z]{3})\s+([A-Z])[0-9]{3}([0-9]{4})([0-9]{2})([0-9]{2})

Dan, karena di sebagian besar dialek regex, \dsama dengan [0-9]:

^(\d{5})+\s+([A-Z]?)\s+([A-Z])(\d{3})(\d{3})([A-Z]{3})([A-Z]{3})\s+([A-Z])\d{3}(\d{4})(\d{2})(\d{2})

Tetapi: apakah Anda benar-benar membutuhkan 11 kelompok penangkapan terpisah? Dan jika demikian, mengapa Anda tidak menangkap kelompok digit keempat hingga terakhir?

Tim Pietzcker
sumber
Tim, sejujurnya saya tidak yakin karena saya tidak menulis regex ini. Saya masih cukup baru untuk regex. Jika Anda melihat cara yang lebih baik untuk menulis ini, saya terbuka untuk saran.
jim
1
Tim, contoh Anda berfungsi untuk kedua string, apakah saya punya surat di posisi itu atau tidak. Terima kasih.
jim
26

Anda dapat membuat satu huruf opsional dengan menambahkan ?setelahnya sebagai:

([A-Z]{1}?)

Kuantifikasi {1}berlebihan sehingga Anda dapat menjatuhkannya.

codaddict
sumber
Terima kasih codeaddict. Apakah tanda tanya menggantikan `+. *? + `?
jim
Saat menggunakan grep regex Anda akan mendapatkan kesalahan jika Anda menjatuhkan {1} (grep: lookbehind pernyataan tidak panjang tetap). Jadi itu alasan untuk meninggalkannya.
Zunderscore
6

Anda juga harus menandai satu huruf sebagai opsional:

([A-Z]{1})? +.*? +

atau menjadikan seluruh bagian opsional

(([A-Z]{1}) +.*? +)?
Stefan
sumber
1
Stefan, aku ingin membuat surat itu sepenuhnya opsional. Saya mencoba kedua hal ini tetapi tetap tidak cocok. Saya yakin saya salah. Bisakah Anda memodifikasi contoh Anda untuk memasukkannya ke dalam string?
jim
0

Anda juga bisa menggunakan regex sederhana yang dirancang untuk kasus Anda seperti di (.*)\/(([^\?\n\r])*)mana $2cocok dengan yang Anda inginkan.

robinvrd
sumber