Проверка возраста Regex - PullRequest
1 голос
/ 10 июня 2010

У кого-нибудь есть хорошее регулярное выражение для проверки возраста?

У меня есть поле даты, в котором я проверяю, что введенное пользователем является датой.

В основном я хотел выяснить, является ли эта дата действительной, а затем дополнительно уточнить дату, чтобыв течение x лет

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

^([1][012]|[0]?[1-9])[/-]([3][01]|[12]\d|[0]?[1-9])[/-](\d{4}|\d{2})$

Ответы [ 5 ]

3 голосов
/ 10 июня 2010

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

НО:

Соответствие действительной дате (без таких сложностей, как проверка на високосные годы) довольно тривиально, но регулярное выражение утомительно - инструмент для создания регулярных выражений, таких как RegexMagic , сделает это за вас быстро:

(?:0?2[/.-](?:[12][0-9]|0?[1-9])|(?:0?[469]|11)[/.-](?:30|[12][0-9]|0?[1-9])|(?:0?[13578]|1[02])[/.-](?:3[01]|[12][0-9]|0?[1-9]))[/.-][0-9]{4}

- это то, что RegexMagic генерирует для проверки даты ММ / ДД / ГГГГ без наложения ограничений на диапазоны дат (т. Е. 31.02.2020 не будет совпадать, 31.014500 будет).

Это уже некрасиво и, вероятно, довольно сложно понять, унаследовал ли ты этот код.

Вторая проблема, а именно проверка по заранее заданному диапазону дат, еще более ужасна. Это можно сделать, но

  1. вам нужно изменить свое регулярное выражение каждый день - в конце концов, каждый день, кому-то исполняется 18 лет, не так ли? и

  2. регулярное выражение станет еще более громоздким. Разрешить что-либо с 10.06.1992 до 10.10.2010, вы получите

этот монстр регулярного выражения.

0?6[/.-](?:30|[12][0-9])[/.-]1992|(?:(?:0?9|11)[/.-](?:30|[12][0-9]|0?[1-9])|
(?:0?[78]|1[02])[/.-](?:3[01]|[12][0-9]|0?[1-9]))[/.-]1992|0?6[/.-](?:10|0?[1-9])
[/.-]2010|(?:0?2[/.-](?:[12][0-9]|0?[1-9])|0?4[/.-](?:30|[12][0-9]|0?[1-9])|0?
[135][/.-](?:3[01]|[12][0-9]|0?[1-9]))[/.-]2010|(?:0?2[/.-](?:[12][0-9]|0?[1-9])|
(?:0?[469]|11)[/.-](?:30|[12][0-9]|0?[1-9])|(?:0?[13578]|1[02])[/.-](?:3[01]|
[12][0-9]|0?[1-9]))[/.-](?:200[0-9]|199[3-9])

(разрывы строк включены для «ясности»).

Завтра тебе понадобится

0?6[/.-](?:30|2[0-9]|1[1-9])[/.-]1992|(?:(?:0?9|11)[/.-](?:30|[12][0-9]|0?[1-9])|
(?:0?[78]|1[02])[/.-](?:3[01]|[12][0-9]|0?[1-9]))[/.-]1992|0?6[/.-](?:1[01]|0?[1-9])
[/.-]2010|(?:0?2[/.-](?:[12][0-9]|0?[1-9])|0?4[/.-](?:30|[12][0-9]|0?[1-9])|0?
[135][/.-](?:3[01]|[12][0-9]|0?[1-9]))[/.-]2010|(?:0?2[/.-](?:[12][0-9]|0?[1-9])|
(?:0?[469]|11)[/.-](?:30|[12][0-9]|0?[1-9])|(?:0?[13578]|1[02])[/.-](?:3[01]|
[12][0-9]|0?[1-9]))[/.-](?:200[0-9]|199[3-9])

Заметили тонкую разницу?

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

1 голос
/ 10 июня 2010

Если вы не можете использовать другой метод, можете ли вы хотя бы рассчитать количество дней между вашей целевой датой рождения и подарком, а затем просто проверить, как this ?это упростило бы необходимость динамической генерации верхнего конца диапазонов дат, таких как [0-minmonthfirstdigit] [0-minmonthseconddigit] и т. д. *

1 голос
/ 10 июня 2010

Вы делаете ошибку, которую, кажется, совершают многие люди (посмотрите на активность в этом теге!): У вас есть цель (в данном случае проверка возраста), и вы решили , что онадолжно быть достигнуто с помощью регулярных выражений.Я не совсем уверен, почему люди делают это - это не так, как регулярное выражение - волшебная панацея, которая решит все ваши проблемы.Лучший вопрос: (а) «Как мне выполнить проверку возраста? Я подумал, может быть, регулярное выражение, но я не уверен, как написать один», или (б) «Я использую технологиюXYZ, и мне нужно выполнить проверку возраста, потому что XYZ структурирован в виде PQR, мне нужно использовать для этого регулярное выражение, но я не уверен, как его написать. "

Так что если выв ситуации (а) я бы сказал так: зачем использовать регулярное выражение?Я не уверен, как вы получаете свой вклад, но, кажется, есть два случая.Если вы получаете одно целочисленное значение для того, сколько им лет, просто прочитайте его откуда угодно, конвертируйте в целое число ( например , через Java Integer.parseInt(myStringInput)), а затемпроверьте, что целое число находится в диапазоне с чем-то вроде return (18 < age) ? true : false.Если вы получаете дату их рождения (как подразумевается под «годами, месяцами и днями»), то: читайте по годам, месяцам и дням;преобразовать их в целые числа;используйте их для создания экземпляра класса Date;и используйте его методы для измерения расстояний между временами (опять же, это зависит от вашего языка).

Если, с другой стороны, вы находитесь в ситуации (б) ... тьфу.Да, это было бы отвратительно.Если вы находитесь в ситуации с одним целым числом, это должно быть выполнимо.Если вы хотите соответствовать, скажем, возрастам больше или равным 18, вы должны сделать что-то вроде ^(1[8-9]|[2-9]\d|\d{3,})$: либо 18, 19, любой возраст из двух цифр выше подросткового возраста, или возраст из трех или более цифр.Если вы хотите соответствовать до 18 лет, то вам нужно ^(\d|1[0-7])$.Если вы находитесь в ситуации рождения ребенка, хотя ... опять, тьфу.Я не уверен, как бы я подошел к этому.Я надеюсь, что нет.Это определенно выполнимо;Я думаю, что правильный подход заключается в том, чтобы сделать что-то подобное вышеописанному.Сопоставьте все годы, которые были до now-18;если год равен now-18, делайте что-то подобное месяцами;и если месяц совпадает, сделайте что-то похожее для дней.Но я надеюсь, что вы не находитесь в такой ситуации.

Редактировать 1: Вы сказали, что написали какую-то структуру проверки для полей, которые предполагали регулярное выражение.Хотя я понимаю, почему это заставит вас хотеть их использовать, это ограничит то, что вы можете проверить (и определенно то, что вы можете проверить разумно).Возможно, имеет смысл вместо этого передать функцию обратного вызова, которая позволит вам иметь дело с регулярным выражением или с такими вещами.

1 голос
/ 10 июня 2010
<label><input type="checkbox" name="old_enough" value="you betcha!" /> I am old enough to visit this website.</label>

Regex: ^you betcha!$

Это не задача для регулярных выражений.

edit: Относительно вашего редактирования ... Зачем пытаться что-то вроде

^([1][012]|[0]?[1-9])[/-]([3][01]|[12]\d|[0]?[1-9])[/-](\d{4}|\d{2})$

когда вы можете просто сделать

if($age >= $minimum) { // verified! }

Если у вас день рождения, вы могли бы сначала сделать что-то подобноепреобразовать день рождения в метки времени (здесь используется PHP):

$minimum = strtotime('-13 years');
$age = strtotime('YYYY-MM-DD');
0 голосов
/ 10 июня 2010

Чтобы проверить, составляет ли возраст 1-109

([1-9][0-9]?)¦(10[1-9])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...