1

Тема: Регулярка для паспорту

Хочу додати українську локалізацію для CakePHP 3
https://github.com/cakephp/localized
В локалізацію входить і валідація базових даних. Індекс, номер телефону, паспорт.
От з валідацією паспорта якраз і проблема.

$pattern = '/^[А-Я\p{Cyrillic}]{2}\d{6}/u';
var_dump(preg_match($pattern, 'кс845696'));

Чому ця регулярка пропускає малі букви? Тут явно ж вказано А-Я. На онлайн сервісах вона працює нормально, але при виконанні на php - ні.

Подякували: 221VOLT1

2

Re: Регулярка для паспорту

Нагадаю, [] в регулярках означає перелік. [AB] означає A або B. X-Y означає діапазон: [A-DX] означає будь-яку з літер ABCDX.
Відповідно, [А-Я\p{Cyrillic}] означає будь-яку з літер АБВ...ЮЯ або будь-яку кирилічну літеру. "к" та "с" - кирилічні, тобто відповідають регулярці.
А взагалі я щось в положенні про паспорт не бачу якихось обмежень на серію, тобто там колись може бути і латинка додана за бажання виробника.

Подякували: leofun01, 221VOLT2

3

Re: Регулярка для паспорту

koala написав:

Нагадаю, [] в регулярках означає перелік. [AB] означає A або B. X-Y означає діапазон: [A-DX] означає будь-яку з літер ABCDX.
Відповідно, [А-Я\p{Cyrillic}] означає будь-яку з літер АБВ...ЮЯ або будь-яку кирилічну літеру. "к" та "с" - кирилічні, тобто відповідають регулярці.
А взагалі я щось в положенні про паспорт не бачу якихось обмежень на серію, тобто там колись може бути і латинка додана за бажання виробника.

Так. Але скажімо з латинкою [a-z] та [A-Z] різні значення. Перше відповідає лише малим літерам а друге лише великим.
Так, але думаю латинка буде уже в новому паспорті. А зараз я хочу просто не пропускати малі літери.

Подякували: 221VOLT1

4

Re: Регулярка для паспорту

Чому не підняти малі літери вже при поверненні результату, через strtoupper() ?
Там має бути суто регулярка?

Подякували: 221VOLT1

5

Re: Регулярка для паспорту

Sensetivity написав:

Так. Але скажімо з латинкою [a-z] та [A-Z] різні значення. Перше відповідає лише малим літерам а друге лише великим.
Так, але думаю латинка буде уже в новому паспорті. А зараз я хочу просто не пропускати малі літери.

Для кирилиці [а-я] та [А-Я] теж має різні значення, яка несподіванка.
А [А-Я1] буде пропускати ще й цифру 1. Що не ясно?

Подякували: leofun01, 221VOLT2

6

Re: Регулярка для паспорту

Забираю свої слова назад, воно не працює з кирилицею..
UPD:
mb_strtoupper() таки працює.

Подякували: koala, leofun01, 221VOLT3

7

Re: Регулярка для паспорту

Вирішив проблему в лоб:

$pattern = '/^[АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯ]{2}\d{6}/u';
Подякували: 221VOLT1

8

Re: Регулярка для паспорту

koala написав:
Sensetivity написав:

Так. Але скажімо з латинкою [a-z] та [A-Z] різні значення. Перше відповідає лише малим літерам а друге лише великим.
Так, але думаю латинка буде уже в новому паспорті. А зараз я хочу просто не пропускати малі літери.

Для кирилиці [а-я] та [А-Я] теж має різні значення, яка несподіванка.
А [А-Я1] буде пропускати ще й цифру 1. Що не ясно?

Усе ясно, тільки воно НЕ працює. А латинкою працює з кирилицею - ні. Принаймні в мому випадку.

Подякували: 221VOLT1

9

Re: Регулярка для паспорту

Sensetivity написав:

Усе ясно, тільки воно НЕ працює. А латинкою працює з кирилицею - ні. Принаймні в мому випадку.

ЩЯРНТ?

Подякували: 221VOLT1

10

Re: Регулярка для паспорту

Sensetivity написав:

Вирішив проблему в лоб:

$pattern = '/^[АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯ]{2}\d{6}/u';

ІМНО найкращий варіант. Діапазон [А-Я] включає також російські літери (крім Ё), але не включає українських ҐЄІЇ. Втім, не впевнений, чи в номерах українських паспортів вони справді використовуються.

Подякували: 221VOLT1

11 Востаннє редагувалося Sensetivity (20.07.2016 12:55:28)

Re: Регулярка для паспорту

Готово.
https://github.com/cakephp/localized/pull/132

P.Y. написав:
Sensetivity написав:

Вирішив проблему в лоб:

$pattern = '/^[АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯ]{2}\d{6}/u';

ІМНО найкращий варіант. Діапазон [А-Я] включає також російські літери (крім Ё), але не включає українських ҐЄІЇ. Втім, не впевнений, чи в номерах українських паспортів вони справді використовуються.

Може й не використовуються але мати підтримку української абетки аніж російської все ж краще.

Подякували: 221VOLT1

12 Востаннє редагувалося ktretyak (24.07.2016 15:13:52)

Re: Регулярка для паспорту

Sensetivity написав:

Вирішив проблему в лоб:

$pattern = '/^[АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯ]{2}\d{6}/u';

На початку теми ви казали про проблеми з діапазоном, бо він не включає малих літер. Цим виразом ви додали ще пару символів, але теж з великих літер. Ви точно вирішили вашу проблему?

А взагалі-то діапазон, який повністю охоплює усі літери українського алфавіту буде мабуть таким:

$pattern = '/^[а-яієїґ]{2}\d{6}/ui';

Зверніть увагу на модифікатор патерна - маленька буква i на кінці регулярки.

Без використання цього модифікатора, треба було б написати так:

$pattern = '/^[А-яієїґІЄЇҐ]{2}\d{6}/u';

Літери ієїґ не входять в діапазон А-я, бо... ну це тема іншої історії про "ненужный украинский язык"...

P.S. Може ще комусь треба регулярку для перевірки валідності email:

/^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;
Подякували: leofun01, funivan2

13

Re: Регулярка для паспорту

Для перевірки валідності email достатньо..

filter_var($email, FILTER_VALIDATE_EMAIL)
Подякували: ktretyak1

14

Re: Регулярка для паспорту

VTrim написав:

Для перевірки валідності email достатньо..

filter_var($email, FILTER_VALIDATE_EMAIL)

О, нарешті вже зробили таку можливість (PHP >= 5.2.0, PHP 7), ще б якось можна було глянути на той патерн, яким вони роблять валідацію.

Подякували: 221VOLT1

15

Re: Регулярка для паспорту

Здається знайшов в сирцях відповідні регулярки для перевірки email, не слабо так:

    const char regexp0[] = "/^(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){255,})(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){65,}@)(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E\\pL\\pN]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F\\pL\\pN]|(?:\\x5C[\\x00-\\x7F]))*\\x22))(?:\\.(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E\\pL\\pN]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F\\pL\\pN]|(?:\\x5C[\\x00-\\x7F]))*\\x22)))*@(?:(?:(?!.*[^.]{64,})(?:(?:(?:xn--)?[a-z0-9]+(?:-+[a-z0-9]+)*\\.){1,126}){1,}(?:(?:[a-z][a-z0-9]*)|(?:(?:xn--)[a-z0-9]+))(?:-+[a-z0-9]+)*)|(?:\\[(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){7})|(?:(?!(?:.*[a-f0-9][:\\]]){7,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?)))|(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){5}:)|(?:(?!(?:.*[a-f0-9]:){5,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3}:)?)))?(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))(?:\\.(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))){3}))\\]))$/iDu";
    const char regexp1[] = "/^(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){255,})(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){65,}@)(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22))(?:\\.(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22)))*@(?:(?:(?!.*[^.]{64,})(?:(?:(?:xn--)?[a-z0-9]+(?:-+[a-z0-9]+)*\\.){1,126}){1,}(?:(?:[a-z][a-z0-9]*)|(?:(?:xn--)[a-z0-9]+))(?:-+[a-z0-9]+)*)|(?:\\[(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){7})|(?:(?!(?:.*[a-f0-9][:\\]]){7,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?)))|(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){5}:)|(?:(?!(?:.*[a-f0-9]:){5,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3}:)?)))?(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))(?:\\.(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))){3}))\\]))$/iD";
Подякували: 221VOLT, leofun012

16

Re: Регулярка для паспорту

@koala на рахунок  http://ideone.com/FyRDi3
для написання регулярки яка матчить букви укр алфавіту треба написати так:

<?php
$pattern = '/^[А-ЯІЇ]{2}\d{6}/u';
echo 'Мала кирилиця: '.preg_match($pattern, 'аі845696').PHP_EOL;
echo 'Велика кирилиця: '.preg_match($pattern, 'АІ845696').PHP_EOL;

Я на даному етапі не можу сказати чому ІЇ не входить в діапазон А-Я.   Але якщо забрати їх то АІ матчитись не буде

2. Для всіх ;)

    filter_var($email, FILTER_VALIDATE_EMAIL)

Чому я не рекомендую використовувати цю штуку:
Якщо ви напишете мояпошта@пошта.укр   (УКР - це є цілком валідний домен)
Функція не пропустить цей email. Відповідно немає сенсу її юзати ;)
Спробуйте:

var_dump(filter_var('мояпошта@домен.укр', FILTER_VALIDATE_EMAIL));
Подякували: leofun011

17

Re: Регулярка для паспорту

funivan, по-перше у вас невірний діапазон алфавіту, див. мій комент.

По-друге, на деяких (припускаю що на більшості) поштових серверах кириличні домени не проходять валідацію саме коли пишуться кирилицею, натомість ось таке страхіття, - проходить

xn--80axgaet5b1c@xn--d1acufc.xn--j1amh

Тобто перед валідацією кириличних доменів просто треба зробити, так би мовити, Punycode до такого вигляду як я показав.

Подякували: leofun011

18

Re: Регулярка для паспорту

ktretyak переглянув ваш комент. Так я помилявся:)
Але все рівно треба робити надбудову над filter_val для того що б перевірити валідність вхідних даних. Трохи не фонтан. Цікаво чому не зробили цієї фішки з коробки. Можливо хтось знає ?;)

19 Востаннє редагувалося ktretyak (14.08.2016 19:07:12)

Re: Регулярка для паспорту

В Node.js це можна зробити досить просто, бо є спеціальний невеличкий модуль Punycode. По-суті для пошти там потрібен лише метод punycode.toASCII().

Стосовно PHP, не знаю про аналог.

20

Re: Регулярка для паспорту

Виходить ні Python ні PHP не можуть сходу перевірити правильність електронної пошти. Дивина та й годі :)
У PHP є така штука http://php.net/manual/ru/function.idn-to-ascii.php