Regex untuk mencocokkan angka dua atau empat kali

95

Ini pertanyaan sederhana tentang ekspresi reguler, tetapi saya tidak menemukan jawabannya.

Saya ingin menentukan apakah suatu angka muncul secara berurutan tepat dua atau empat kali. Sintaks apa yang dapat saya gunakan?

\d{what goes here?}

Saya mencoba \d{2,4}, tetapi ungkapan ini menerima tiga digit juga.

Renato Dinhani
sumber
1
Misalnya, untuk mencocokkan dua atau empat digit tahun .
DavidRR
Apa yang Anda inginkan terjadi jika string adalah abc 123 xyz? Haruskah itu cocok 12karena persis dua digit berurutan? Atau seharusnya tidak, karena 12merupakan bagian dari deret digit yang lebih besar 123yang panjangnya bukan 2 atau 4? Jika saya harus menebak, saya pikir Anda menginginkan perilaku yang terakhir, tetapi pertanyaan Anda tidak jelas. Contoh dan / atau spesifikasi yang lebih jelas akan membantu. Pertanyaan yang sama untuk abc 12345 def... apa yang harus terjadi di sana?
Jean-François Corbett

Jawaban:

146

Tidak ada sintaks khusus untuk itu, tetapi ada banyak cara untuk melakukannya:

(?:\d{4}|\d{2})    <-- alternation: four digits or two
\d{2}(?:\d{2})?    <-- two digits, and optionally two more
(?:\d{2}){1,2}     <-- two digits, times one or two
ruakh
sumber
1
Secara pribadi, hanya memikirkan \d{2}(?:\d{2})?solusi langsung - variasi bagus dari ini - yang terakhir, khususnya, tampak sangat bagus dan terukur.
Nightfirecat
3
1 untuk memperhatikan urutan yang diperlukan saat menggunakan pergantian untuk mencocokkan 4 digit terlebih dahulu, lalu 2 digit. Kerja bagus juga menyediakan variasi lainnya.
Ahmad Mageed
9
Bagi siapa pun yang, seperti saya, tidak memahami penggunaan (?:ini memulai "grup non-capturing" (grup yang tidak dimaksudkan untuk direferensikan dalam pernyataan ganti). Anda juga bisa menggunakan tanda kurung tetapi ini akan membuat grup penangkap. Rincian lebih lanjut di sini: stackoverflow.com/questions/3512471/non-capturing-group
Jeremy Moritz
Ini akan menunjukkan hasil yang sama untuk "333" dan "33"
Dan
1
@Dan: Regex ini tidak cocok dengan string lengkap "333". Anda mungkin tidak sengaja menggunakan fungsi "temukan substring yang cocok" dari perpustakaan regex, daripada fungsi "periksa apakah string lengkap cocok". Anda harus berkonsultasi dengan dokumentasinya.
ruakh
3
(?<!\d)(\d{2}|\d{4})(?!\d)

Ini adalah cara yang benar untuk melakukannya. Jawaban yang diterima salah.

Ini akan cocok dengan 3 digit (atau 5). Jadi itu salah di mata saya .

1) Pastikan tidak ada digit sebelum urutan 2, atau 4 digit, atau setelah urutan dua atau empat digit.

  • (<!) sintaks terlihat negatif di belakang

  • (?!) sintaks adalah lookahead negatif.

Cara di atas akan berfungsi untuk senar tengah:

Jika string pencarian Anda tidak memiliki konten di sekitarnya Anda bisa menggunakan ^dan $memulai dan mengakhiri jangkar tali:

^\d{4}$|^\d{2}$
JGFMK
sumber
1
Saya tidak akan mengatakan bahwa jawaban yang diterima salah. Saya akan mengatakan pertanyaannya tidak jelas, dan jawaban itu membahas satu interpretasi yang valid darinya. Jawaban Anda membahas interpretasi valid lainnya (yang menurut saya lebih mungkin - tetapi tampaknya penanya tidak ...).
Jean-François Corbett
2
"Ini akan cocok dengan 3 digit" tidak cukup akurat. Saya pikir maksud Anda "Ini akan cocok dengan urutan 2 digit dari urutan 3 digit."
Jean-François Corbett
1
Selain itu, jawaban Anda tidak berfungsi sebagaimana mestinya pada urutan 5 digit atau lebih . Saya bukan ahli regex, tapi saya kira satu cara untuk memperbaikinya adalah dengan membuat lookahead / belakang negatif berlaku untuk kedua kasus (urutan 2 dan 4 digit):(?<!\d)(\d{2}|\d{4})(?!\d)
Jean-François Corbett
Saya pikir Anda benar tentang 5 digit. Terima kasih atas koreksi itu. Akan memperbaikinya.
JGFMK
^\d{4}$|^\d{2}$akan menjadi cara potensial untuk memperbaikinya. Seperti yang akan^\d{2}(?!\d)|^\d{4}(?!\d)
JGFMK