2010-06-10 2 views
1

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

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

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

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

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

... что спецификация? – polygenelubricants

+4

Зачем вам использовать регулярное выражение для этого? – ceejayoz

+1

Да, регулярное выражение здесь не подходит, но удачи в любом случае. –

ответ

3

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

НО:

Matching действительную дату (без фантазии вещи, как проверка на високосные годы) довольно тривиально, но утомительно с помощью регулярных выражений - это инструмент для построения регулярных выражений, как 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 генерирует для проверки даты MM/DD/YYYY без введения ограничений на диапазоны дат (то есть 02/31/2020 не будет соответствовать, 01/31/4500 будет).

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

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

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

  2. Регулярное выражение будет еще более громоздким. Чтобы разрешить что-либо от 06/10/1992 до 06/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]) 

(linebreaks included for "clarity").

Завтра, вы будете нуждаться в

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]) 

Обратите внимание на тонкое различие?

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

+0

Я думал о том, как алгоритмически подойти, и я полностью забыл вопрос «42 декабря», а тем более «31 июня». Черт ... это хуже, чем я ожидал. –

1
<label><input type="checkbox" name="old_enough" value="you betcha!" /> I am old enough to visit this website.</label> 

Regex: ^you betcha!$

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

редактировать: Что касается правки ... Зачем пытаться что-то вроде

^([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

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

+0

К сожалению, вы не будете работать, так как нам нужна дата рождения пользователя для юридических целей. – KevinDeus

+3

Использование регулярного выражения для такого рода вещей - это определение ** un ** clean. – ceejayoz

0

Чтобы проверить, если возраст между 1-109

([1-9][0-9]?)¦(10[1-9]) 
+2

110-летние не должны применяться. – Welbog

+0

Возраст зависит от текущей даты. Кажется, это проверяет число. – KevinDeus

+2

Вот почему кто-то сказал: «Что такое спецификация?» в комментариях. Вы не сказали нам, какие данные пользователь должен ввести - проверяют ли они поле, вводят день рождения или вводят числовое число лет? – ceejayoz

1

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

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

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

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

+0

+1 для опции обратного вызова. – ceejayoz

+0

Antal, ваши комментарии полезны, и я полностью согласен с вашими точками о том, где работа будет лучше использоваться, но выход за рамки вопроса приводит к гораздо большему количеству областей, чем это необходимо. Может быть, имеет смысл использовать другой метод, и это вариант, но, не вдаваясь в целую архитектуру проекта, делает ли он недействительным возможность создавать регулярное выражение? – KevinDeus

+0

Делает это * невозможно *? Нет, потому что у вас есть конечное число строк, чтобы соответствовать (предполагая, что вы ограничиваете себя четырехзначными годами), чтобы вы могли (но не хотели) построить его с помощью гигантского '' 'утверждения. Не страшно ли писать? Да, это действительно так. И, как и кто-то другой, обратите внимание, что * невозможно * использовать regexen для проверки некоторых других классов ввода! –

1

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