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})/

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, 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.


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}) +.*? +)?

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.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.