|
|
|
| Здравствуйте,
Столкнулся с тем, что не получается составить следующие регулярное выражение:
В форме существует поле, в которое можно вводить символы a-z (нижний регистр, латиница), цифры 0-9 и - (дефис). Помимо этого необходимо проверять поле на такой фактор, что нельзя, чтобы один символ повторялся более 3 раз подряд, а цифры, независимо одинаковые или нет, также не повторялись более 3 раз подряд и не более 5 раз во всей строке.
Проверку на латиницу, цифры, дефис сделал, это не сложно, а вот с количеством повторений завис. Очень рассчитываю на Вашу помощь.
С Уважением, Дмитрий. | |
|
|
|
|
|
|
|
для: Desh
(29.08.2009 в 23:02)
| | символы подряд отсекаются опережающей (или ретроспективной - дело вкуса) проверкой.
А общее число цифр проще проверить не регулярками, а функцией count_chars() | |
|
|
|
|
|
|
|
для: Trianon
(29.08.2009 в 23:28)
| | Про функцию count_chars() понял, как-то даже сразу в голову не пришла, большое спасибо)
А вот про ретроспективную проверку, увы, не понял. С регулярными выражениями дружу не особо, хотя вещь порой просто незаменимая. Просмотрел статьи на эту тему...понял очень мало, к сожалению. Можно небольшой примерчик? | |
|
|
|
|
|
|
|
для: Desh
(29.08.2009 в 23:51)
| | как-то так
/^[-a-z0-9]+(?<!.*[0-9]{3}.*)$/
|
| |
|
|
|
|
|
|
|
для: Trianon
(30.08.2009 в 00:00)
| | дико извиняюсь , но как-то так не пойдёт :)
такие ретроспективные подмаски не могут содержать + или * квантификаторов совсем
ибо Compilation failed: lookbehind assertion is not fixed length
и почему-то даже (?:([-0-9a-z])(?<!(?:\d|\1){3}))+ не проходит , хотя в \1 тоже только один символ
а например (?<!(?:\d|\D){3}) проходит.
Можно применить наоборот такие (?!) (?=) подмаски
, но придётся их так-же подставлять после каждого прошедшего символа
'#^(?:(?!\d{3}|\1{2})([-0-9a-z]))+$#'
| здесь побочный эффект , три дефиса тоже не пройдёт | |
|
|
|
|
|
|
|
для: heed
(30.08.2009 в 04:01)
| | точно. Ляпнул.
Но в опережающих могут быть. | |
|
|
|
|
|
|
|
для: Trianon
(30.08.2009 в 09:12)
| |
$p = '/^((?!.*[\\d]{3}.*)(?!.*?(.)\\2{2}.*)[-a-z0-9]+)$/';
|
| |
|
|
|
|
|
|
|
для: Trianon
(30.08.2009 в 12:47)
| | (?!.*[\\d]{3}.*) поправьте если ошибаюсь: если логин указан верно, первая *, в силу своей жадности, будет каждый раз доходить до конца строки и отступать на прежнее место. | |
|
|
|
|
|
|
|
для: ride
(31.08.2009 в 10:40)
| | на самом деле я перемудрил.
достаточно так (?!.*[\\d]{3})
или даже так (?!.*\\d{3})
читается как
впереди не должно встретиться, после любых символов в любом количестве , цифр подряд в количестве 3 штуки.
А жадность... жадность и вправду можно уменьшить, чтоб производительность не страдала.
(?!.*?\\d{3}) | |
|
|
|
|
|
|
|
для: Trianon
(31.08.2009 в 10:58)
| | думаю .* вообще надо убрать. | |
|
|
|
|
|
|
|
для: ride
(31.08.2009 в 11:11)
| | Возможно. | |
|
|
|
|
|
|
|
для: ride
(31.08.2009 в 11:11)
| | Какой у Вас получился шаблон в конечном итоге? | |
|
|
|
|
|
|
|
для: Trianon
(31.08.2009 в 12:00)
| | я склоняюсь к предложенному мной варианту(только добавлю дефис)
([-a-z0-9])(?=\d{3}|\1{3})
//использовать так
$pattern='/([-a-z0-9])(?=\d{3}|\1{3})/i';
$subject='342str';
if(preg_match($pattern,$subject)){
echo'Логин указан неверно';
}else echo'все ок!';
|
| |
|
|
|
|
|
|
|
для: ride
(31.08.2009 в 12:59)
| | попытка ввести любой символ за пределами набора приводит к диагностике "все ок!" | |
|
|
|
|
|
|
|
для: Trianon
(31.08.2009 в 13:05)
| | согласен, не учел это
([-a-z0-9])(?=\d{3}|\1{3}|[^a-z0-9-])
|
теперь все ок
upd почти)) | |
|
|
|
|
|
|
|
для: ride
(31.08.2009 в 13:11)
| | $pattern = ? | |
|
|
|
|
|
|
|
для: Trianon
(31.08.2009 в 13:20)
| | тогда еще упрощу
(?=\d{4}|[^a-z0-9-]|(.)\1{3})
|
| |
|
|
|
|
|
|
|
для: heed
(30.08.2009 в 04:01)
| | так с дефисами можно
([a-z0-9])(?=\d{3}|\1{3})
|
| |
|
|
|
|
|
|
|
для: Desh
(29.08.2009 в 23:02)
| | Большое спасибо за варианты.
Но подошёл вот этот:
$p = '/^((?!.*[\\d]{3}.*)(?!.*?(.)\\2{2}.*)[-a-z0-9]+)$/';
// by Trianon
|
К сожалению, другие варианты срабатывают не верно или не так как я себе это представляю (возможно, не так описал задачу в первом топе).
P. S. Тут появился вопрос: как можно доработать вышенаписанное регулярное выражение, чтобы дефис не мог повторяться более двух раз подряд? | |
|
|
|
|
|
|
|
для: Desh
(30.08.2009 в 16:22)
| | >P. S. Тут появился вопрос: как можно доработать вышенаписанное регулярное выражение, чтобы дефис не мог повторяться более двух раз подряд?
Для этого его следует понять. | |
|
|
|
|
|
|
|
для: Trianon
(30.08.2009 в 18:05)
| | Честно, абсолютно точно понять выражение не смог, всё же стоит в ближайшее время вникнуть в тему регулярных выражений.
Тем не менее, сделал проверку на двойной дефис подряд с помощью функции strpos(). Если она возвращает значение отличное от нуля, то программа считает, что в строке содержится двойной дефис и приостанавливает работу. Вроде верно. | |
|
|
|
|
|
|
|
для: Desh
(30.08.2009 в 18:45)
| | >значение отличное от нуля
это не то
>strpos() может возвращать как логическое значение FALSE, так и не относящееся к логическому типу значение, которое приводится к FALSE, например, 0
проверяйте на значение FALSE
или такое утверждение (?!.*-{2}) говорит о том что во всей последующей строке не должно быть двух дефисов подряд
// или так (?!.*--) | |
|
|
|