Сопоставление регулярных выражений для проверки действительного года

Учитывая значение, я хочу проверить его, чтобы проверить, является ли это действительным годом. Мои критерии просты: значение должно быть целым числом с 4 символами. Я знаю, что это не лучшее решение, поскольку оно не позволит лет до 1000 и позволит таких лет, как 5000. Этот критерий адекватен моему текущему сценарию.

То, что я придумал, это

\d{4}$

Хотя это работает, оно также допускает отрицательные значения.

Как убедиться, что разрешены только положительные целые числа?


person Ranhiru Jude Cooray    schedule 07.12.2010    source источник
comment
Между прочим, я создал проект node.js, to-regex-range, чтобы автоматически создавать эти диапазоны. Это сложнее, чем может показаться, если вам нужно сгенерировать регулярное выражение для тестирования в течение нескольких лет.   -  person jonschlinkert    schedule 29.05.2017
comment
Зачем ограничивать валидацию 4-значным годом? longnow.org   -  person Dan Temple    schedule 27.02.2019


Ответы (15)


Вам нужно добавить начальный якорь ^ как:

^\d{4}$

Ваше регулярное выражение \d{4}$ будет соответствовать строкам, оканчивающимся четырьмя цифрами. Таким образом, ввод типа -1234 будет принят.

Добавляя начальный якорь, вы сопоставляете только те строки, которые начинаются и заканчиваются четырьмя цифрами, что фактически означает, что они должны содержать только четыре цифры.

person codaddict    schedule 07.12.2010
comment
Проклятие! Мой был настолько испорчен, что даже принял бы whateverblahblah2323. Теперь я понимаю, почему небольшое обучение опасно :O - person Ranhiru Jude Cooray; 07.12.2010
comment
Это сломается в 10000 году. - person sferik; 03.09.2012
comment
@sferik: Не имеет значения. В оригинальном плакате прямо говорилось, что он хочет проверить четыре символа. Он не заявил, что хочет, чтобы год 10 000 был допустимым вводом, поэтому принятие 10000 было бы ошибкой. - person markusk; 01.02.2015
comment
@sferik: К тому времени программа исчезнет на века. Если нет, то лучше побеспокоиться о будущем на 9000 лет. Следуя принципу ЯГНИ, подход действителен. - person Phil; 05.01.2018

Годы с 1000 по 2999

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

За 1900-2099 гг.

^(19|20)\d{2}$
person r92    schedule 07.12.2010
comment
Это гораздо лучшее решение - person mk_89; 13.10.2012
comment
Лучше использовать группу без захвата: ^(?:19|20)\d{2}$ - person Eldar Agalarov; 21.06.2015
comment
Как мне проверить четырехзначный год между 2011 и 2099 годами? - person mcquaim; 30.05.2017
comment
Как я могу добавить (19|20)\d{2} к моему регулярному выражению, чтобы проверить формат даты рождения? Это мое регулярное выражение /^[0-9]{1,2}\/(0[1-9])|(1[0-2])\/[0-9]{4}$/ Я хочу, чтобы год всегда состоял из 4 цифр и начинался с 19** или 20** - person ltdev; 10.08.2017
comment
Используйте ^(19|2[0-9])\d{2}$ для 1900–2999 годов. - person MarcoZen; 11.05.2018

«Принятый» ответ на этот вопрос одновременно неверен и близорук.

Это неправильно, поскольку он будет соответствовать таким строкам, как 0001, что не является допустимым годом.

Он близорук в том смысле, что не будет соответствовать значениям выше 9999. Неужели мы уже забыли уроки 2000 года< /а>? Вместо этого используйте регулярное выражение:

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

Если вам нужно сопоставить годы в прошлом, в дополнение к годам в будущем, вы можете использовать это регулярное выражение для соответствия любому положительному целому числу:

^[1-9]\d*$

Даже если вы не ожидаете дат из прошлого, вы все равно можете использовать это регулярное выражение на тот случай, если кто-то изобретет машину времени и захочет забрать ваше программное обеспечение с собой.

Примечание. Это регулярное выражение будет соответствовать всем годам, в том числе годам до 1, поскольку они обычно представлены обозначением до н.э. вместо отрицательного целого числа. Конечно, это соглашение может измениться в течение следующих нескольких тысячелетий, поэтому лучше всего сопоставлять любое целое число — положительное или отрицательное — со следующим регулярным выражением:

^-?[1-9]\d*$
person sferik    schedule 03.09.2012
comment
Нет, скорее всего не будет. Но кому-то (археологу? историку?) может понадобиться сопоставить годы с 8000-летней давностью. :D И Доку Брауну это может понадобиться... - person Jaime; 24.06.2014
comment
я использовал это, чтобы ограничить диапазон от 1000-9999 ^[1-9]\\d{3}$, потому что приложение, которому мы должны предоставить данные, принимает только 4-значные числа :( - person MatPag; 16.11.2015
comment
Потрясающий ответ. Я бы сделал так, чтобы принять год 0: ^(-?[1-9]\d*|0)$ - person Kosta Kontos; 15.12.2016

Это работает с 1900 по 2099 год:

/(?:(?:19|20)[0-9]{2})/
person jonschlinkert    schedule 01.02.2015
comment
мне кажется, что это будет только 2099. Кстати, ОП спрашивает, как разрешить только положительное 4-значное число. - person DeanOC; 01.02.2015
comment
ага, 2099 я имел в виду. Благодарю. и теперь я вижу часть положительных целых чисел. - person jonschlinkert; 01.02.2015
comment
Я создал проект to-regex-range для автоматического создания этих диапазонов. - person jonschlinkert; 17.08.2015

Основываясь на ответе @ r92, за 1970-2019 годы:

(19[789]\d|20[01]\d)
person Renaud    schedule 27.06.2013
comment
Ваш ответ позволяет 197999 - person avalanche1; 08.09.2016
comment
Я не думаю, что это так... Первая часть регулярного выражения соответствует числу, начинающемуся с 19, затем любому из 7,8 или 9, за которым следует ОДНО число. Регулярное выражение 19[789]\d\d\d позволит 197999 - person Renaud; 09.09.2016
comment
да, он будет соответствовать первым 4 числам (1970), а не последним 3. А как насчет (19[789]\d|20[01]\d)[^0-9]? Это соответствует 1970 324, но не 1970324. - person Renaud; 13.09.2016
comment
Я нашел это полезным для поиска года фильма по имени файла ... в этом случае нам нужны материалы с 1930-х годов ... но затем мы исключаем 1024, который добавляется в конец для качества видео. - person Adrian Hum; 29.01.2020

Чтобы проверить год в строке, которая содержит другие слова вместе с годом, вы можете использовать следующее регулярное выражение: \b\d{4}\b

person Dhyey    schedule 09.06.2017
comment
Это было именно то, что мне было нужно, принятый ответ не кажется действительным PCRE. - person Hashim Aziz; 29.11.2018

Теоретически 4-значный вариант подходит. Но на практике лучше иметь диапазон 1900-2099.

Кроме того, это должна быть группа без захвата. Во многих комментариях и ответах предлагается группировка захвата, что, ИМХО, является неправильным. Потому что для сопоставления это может работать, но для извлечения совпадений с использованием регулярного выражения оно будет извлекать 4-значные числа и двузначные (19 и 20) числа также из-за круглых скобок.

Это будет работать для точного сопоставления с использованием групп без захвата:

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

person Adil Aliyev    schedule 16.04.2018

вы можете использовать что-то вроде [^-]\d{4}$: вы не допускаете, чтобы знак минус - стоял перед вашими 4 цифрами.
вы также можете использовать ^\d{4}$ с ^, чтобы поймать начало строки. На самом деле это зависит от вашего сценария...

person PierrOz    schedule 07.12.2010

Использовать;

^(19|[2-9][0-9])\d{2}$ 

за 1900 - 9999 годы.

Не нужно беспокоиться о 9999 и последующих версиях - A.I. будет делать все программирование к тому времени !!! Хе-хе-хе

Вы можете протестировать регулярное выражение на странице https://regex101.com/.

Также больше информации о группах без захвата (упомянутых в одном из комментариев выше) здесь http://www.manifold.net/doc/radian/why_do_non-capture_groups_exist_.htm

person MarcoZen    schedule 11.05.2018

Вы можете преобразовать целое число в строку. Поскольку знак минус не будет соответствовать цифрам, у вас не будет отрицательных лет.

person Comradin    schedule 07.12.2010

Я использую это регулярное выражение в Java ^(0[1-9]|1[012])[/](0[1-9]|[12][0-9]|3[01])[/](19|[2-9][0-9])[0-9]{2}$

Работает с 1900 по 9999 год.

person R2Rivs    schedule 22.01.2015

/^\d{4}$/ Проверяет, состоит ли строка только из 4 чисел. В этом случае, чтобы ввести год 989, вместо него можно указать 0989.

person Dayz    schedule 18.04.2017

Если вам нужно сопоставить YYYY или YYYYMMDD, вы можете использовать:

^((?:(?:(?:(?:(?:[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})$
person Benjamin Goodacre    schedule 19.06.2018
comment
Как преобразовать ГГГГММДД или ДДММГГГГ в ГГГГ.ММ.ДД или ДД.ММ.ГГГГ. У меня есть строка типа 20200315, и я хочу преобразовать ее в 2020.03.15 в Dart. Также входящая строка может быть 17042021, тогда мне нужно преобразовать ее в 17.04.2020 в Dart. Спасибо - person NTMS; 04.03.2021

Вы также можете использовать этот.

([0-2][0-9]|3[0-1])\/([0-1][0-2])\/(19[789]\d|20[01]\d)
person Ranjeet Chouhan    schedule 20.08.2019
comment
Они хотят соответствовать только году. Более того, ваше регулярное выражение соответствует 00/00/2000 или 31/02/1999 и многим другим ложным датам. - person Toto; 20.08.2019
comment
Это может вам помочь ([0-2][0-9]|3[0-1])\/([0-1][0-2])\/(19[789]\d|20[01 ]\г) - person Ranjeet Chouhan; 22.08.2019
comment
(0[1-9]|1[0-2]) - гораздо лучшее выражение для месяца - person EZ-C; 26.09.2019

В моем случае я хотел сопоставить строку, которая заканчивается годом (4 цифры), например, так:

Oct 2020
Nov 2020
Dec 2020
Jan 2021

Он вернет true с этим:

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

Приведенный выше код используется в скрипте приложений.

Вот ссылка для тестирования Regex выше: https://regex101.com/r/SzYQLN/1

person Leniel Maccaferri    schedule 07.01.2021
comment
Это не только будет соответствовать Oct 2020, но и Oct 20202, Oct20202 - person Ranhiru Jude Cooray; 08.01.2021
comment
@RanhiruJudeCooray улучшил регулярное выражение. - person Leniel Maccaferri; 09.01.2021