Pencocokan Persamaan Reguler untuk menguji tahun yang valid

92

Diberikan nilai, saya ingin memvalidasinya untuk memeriksa apakah itu tahun yang valid. Kriteria saya sederhana dimana nilainya harus berupa integer dengan 4karakter. Saya tahu ini bukan solusi terbaik karena tidak akan memungkinkan bertahun-tahun sebelumnya 1000dan akan memungkinkan tahun-tahun seperti itu 5000. Kriteria ini cukup untuk skenario saya saat ini.

Apa yang saya pikirkan adalah

\d{4}$

Sementara ini berhasil, ini juga memungkinkan nilai negatif.

Bagaimana cara memastikan bahwa hanya bilangan bulat positif yang diperbolehkan?

Ranhiru Jude Cooray
sumber
fwiw Saya membuat proyek node.js, to-regex-range untuk secara otomatis membuat rentang ini. Ini lebih sulit daripada yang terlihat jika Anda perlu membuat regex untuk diuji selama beberapa tahun.
jonschlinkert
Mengapa membatasi validasi Anda menjadi 4 digit tahun? longnow.org
Dan Temple

Jawaban:

78

Anda perlu menambahkan jangkar awal ^sebagai:

^\d{4}$

Regex Anda \d{4}$akan cocok dengan string yang diakhiri dengan 4 digit . Jadi masukan suka -1234akan diterima.

Dengan menambahkan jangkar awal, Anda hanya mencocokkan string yang dimulai dan diakhiri dengan 4 digit, yang secara efektif berarti harus berisi hanya 4 digit.

codaddict
sumber
2
Sial! Punyaku begitu cacat sehingga bahkan akan diterima whateverblahblah2323. Sekarang saya mengerti mengapa sedikit belajar itu berbahaya: O
Ranhiru Jude Cooray
62
Ini akan pecah di tahun 10.000.
sferik
16
@sferik: Tidak masalah. Poster asli secara khusus menyatakan dia ingin memeriksa empat karakter. Dia tidak menyatakan dia ingin tahun 10.000 menjadi masukan yang valid, jadi menerima 10000akan menjadi bug.
markusk
4
@sferik: Program akan hilang selama berabad-abad saat itu. Jika tidak, yang terbaik adalah mengkhawatirkan 9.000 tahun yang akan datang. Mengikuti prinsip YAGNI, pendekatan tersebut valid.
Phil
183

Tahun dari 1000 hingga 2999

^[12][0-9]{3}$

Untuk 1900-2099

^(19|20)\d{2}$
r92
sumber
14
Ini adalah solusi yang jauh lebih baik
mk_89
10
Saya lebih baik menggunakan grup non-penangkap:^(?:19|20)\d{2}$
Eldar Agalarov
Bagaimana saya akan memvalidasi tahun 4 digit antara 2011 & 2099?
mcquaim
Bagaimana cara menambahkan (19|20)\d{2}regex saya untuk memvalidasi format tanggal lahir? Ini regex saya, /^[0-9]{1,2}\/(0[1-9])|(1[0-2])\/[0-9]{4}$/saya ingin memastikan bahwa tahun selalu 4 digit dan dimulai dengan 19 ** atau 20 **
ltdev
Gunakan ^ (19 | 2 [0-9]) \ d {2} $ selama tahun 1900 - 2999
MarcoZen
22

Jawaban yang "diterima" untuk pertanyaan ini salah dan rabun.

Itu tidak benar karena akan cocok dengan string seperti 0001, yang bukan merupakan tahun yang valid.

Hal ini di rabun bahwa hal itu akan tidak sesuai dengan nilai setiap atas 9999. Memiliki kita sudah lupa pelajaran dari Y2K ? Sebagai gantinya, gunakan ekspresi reguler:

^[1-9]\d{3,}$

Jika Anda perlu mencocokkan tahun-tahun yang lalu, selain tahun-tahun mendatang, Anda dapat menggunakan persamaan reguler ini untuk mencocokkan bilangan bulat positif mana pun:

^[1-9]\d*$

Bahkan jika Anda tidak mengharapkan tanggal dari masa lalu, Anda mungkin ingin menggunakan ekspresi reguler ini, untuk berjaga-jaga jika seseorang menemukan mesin waktu dan ingin membawa kembali perangkat lunak Anda.

Catatan: Ekspresi reguler ini akan cocok dengan semua tahun, termasuk yang sebelum tahun 1, karena mereka biasanya diwakili dengan sebutan BC dan bukan bilangan bulat negatif. Tentu saja, konvensi ini dapat berubah selama beberapa milenium ke depan, jadi opsi terbaik Anda adalah mencocokkan bilangan bulat apa pun — positif atau negatif — dengan ekspresi reguler berikut:

^-?[1-9]\d*$
sferik
sumber
3
Tidak, sepertinya tidak akan. Tapi seseorang (arkeolog? Sejarawan?) Mungkin perlu mencocokkan tahun 8000 tahun yang lalu. : D Dan Doc Brown mungkin membutuhkannya ...
Jaime
1
saya menggunakan ini untuk membatasi rentang dari 1000-9999 ^ [1-9] \\ d {3} $ thats karena aplikasi kami harus menyediakan data, hanya menerima 4 digit angka :(
MatPag
Jawaban yang luar biasa. Saya akan membuatnya sebagai berikut untuk menerima tahun 0 juga: ^ (-? [1-9] \ d * | 0) $
Kosta Kontos
10

Ini berfungsi untuk tahun 1900 hingga 2099:

/(?:(?:19|20)[0-9]{2})/
jonschlinkert
sumber
menurut saya seperti itu hanya akan pergi ke 2099. BTW OP menanyakan bagaimana hanya mengizinkan angka 4 digit positif.
DeanOC
bah, 2099 yang saya maksud. Terima kasih. dan sekarang saya melihat bagian bilangan bulat positif.
jonschlinkert
Saya membuat proyek, ke-regex-range untuk membuat rentang ini secara otomatis
jonschlinkert
5

Berdasarkan jawaban @ r92, selama tahun 1970-2019:

(19[789]\d|20[01]\d)
Renaud
sumber
Jawaban Anda memungkinkan197999
avalanche1
Saya rasa tidak ... Bagian pertama dari nomor pertandingan regex dimulai dengan 19, lalu salah satu dari 7,8 atau 9, diikuti dengan nomor TUNGGAL. Regex 19[789]\d\d\dakan memungkinkan197999
Renaud
1
/(19[789]\d|20[01]\d)/.test(1970324) >> true
longsoran
ya, itu akan cocok dengan 4 angka pertama ( 1970), bukan 3 terakhir. Bagaimana (19[789]\d|20[01]\d)[^0-9]? Itu akan cocok 1970 324tetapi tidak1970324
Renaud
1
Saya menemukan yang ini berguna untuk menemukan tahun film dari nama file ... dalam hal ini kami menginginkan barang-barang dari tahun 1930-an dan seterusnya ... tetapi kami kemudian mengecualikan 1024 yang ditambahkan ke bagian akhir untuk kualitas video
Adrian Hum
2

Untuk menguji satu tahun dalam string yang berisi kata lain beserta tahun, Anda dapat menggunakan regex berikut: \ b \ d {4} \ b

Dhyey
sumber
Inilah yang saya butuhkan, jawaban yang diterima tampaknya bukan PCRE yang valid.
Prometheus
2

Secara teori, opsi 4 digit adalah benar. Namun dalam praktiknya mungkin lebih baik memiliki rentang 1900-2099.

Selain itu, perlu grup non-penangkap. Banyak komentar dan jawaban mengusulkan pengelompokan menangkap yang IMHO tidak tepat. Karena untuk mencocokkan mungkin berhasil, tetapi untuk mengekstrak kecocokan menggunakan regex akan mengekstrak 4 digit angka dan dua digit (19 dan 20) angka juga karena tanda kurung.

Ini akan berfungsi untuk pencocokan tepat menggunakan grup non-penangkap:

(?:19|20)\d{2}

Adil Aliyev
sumber
1

Anda bisa menggunakan sth seperti [ ^-]\d{4}$: Anda mencegah tanda minus -berada sebelum 4 digit Anda.
Anda juga bisa menggunakan ^\d{4}$with ^untuk menangkap awal string. Itu tergantung pada skenario Anda sebenarnya ...

PierrOz
sumber
0

Anda bisa mengubah integer Anda menjadi string. Karena tanda minus tidak akan cocok dengan angka-angka tersebut, Anda tidak akan memiliki tahun-tahun negatif.

Comradin
sumber
0

Saya menggunakan regex ini di Java ^(0[1-9]|1[012])[/](0[1-9]|[12][0-9]|3[01])[/](19|[2-9][0-9])[0-9]{2}$

Bekerja dari 1900 hingga 9999

R2Rivs
sumber
0

/ ^ \ d {4} $ / Ini akan memeriksa apakah string hanya terdiri dari 4 angka. Dalam skenario ini, untuk memasukkan tahun 989, Anda dapat memberikan 0989 sebagai gantinya.

Dayz
sumber
0

Jika Anda perlu mencocokkan YYYY atau YYYYMMDD, Anda dapat menggunakan:

^((?:(?:(?:(?:(?:[1-9]\d)(?:0[48]|[2468][048]|[13579][26])|(?:(?:[2468][048]|[13579][26])00))(?:0?2(?:29)))|(?:(?:[1-9]\d{3})(?:(?:(?:0?[13578]|1[02])(?:31))|(?:(?:0?[13-9]|1[0-2])(?:29|30))|(?:(?:0?[1-9])|(?:1[0-2]))(?:0?[1-9]|1\d|2[0-8])))))|(?:19|20)\d{2})$
Benjamin Goodacre
sumber
0

Anda juga bisa menggunakan yang ini.

([0-2][0-9]|3[0-1])\/([0-1][0-2])\/(19[789]\d|20[01]\d)
Ranjeet Chouhan
sumber
Mereka ingin mencocokkan tahun saja. Apalagi regex Anda cocok 00/00/2000atau 31/02/1999dan banyak lagi tanggal palsu.
Toto
Apakah dapat membantu Anda ([0-2] [0-9] | 3 [0-1]) \ / ([0-1] [0-2]) \ / (19 [789] \ d | 20 [01 ] \ d)
Ranjeet Chouhan
(0[1-9]|1[0-2])adalah ekspresi yang jauh lebih baik untuk bulan ini
EZ-C
0

Dalam kasus saya, saya ingin mencocokkan string yang diakhiri dengan satu tahun (4 digit) seperti ini misalnya:

Oct 2020
Nov 2020
Dec 2020
Jan 2021

Ini akan kembali truedengan yang ini:

var sheetName = 'Jan 2021';
var yearRegex = new RegExp("\\d{4}$");
var isMonthSheet = yearRegex.test(sheetName);
Logger.log('isMonthSheet = ' + isMonthSheet);

Kode di atas digunakan dalam Apps Script .

Leniel Maccaferri
sumber
Ini, tidak hanya akan cocok Oct 2020tetapi juga Oct 20202, Oct20202
Ranhiru Jude Cooray