Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум Регулярные Выражения

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Символы a-z (нижний регистр, латиница), цифры 0-9 и - (дефис)
 
 автор: Desh   (29.08.2009 в 23:02)   письмо автору
 
 

Здравствуйте,
Столкнулся с тем, что не получается составить следующие регулярное выражение:

В форме существует поле, в которое можно вводить символы a-z (нижний регистр, латиница), цифры 0-9 и - (дефис). Помимо этого необходимо проверять поле на такой фактор, что нельзя, чтобы один символ повторялся более 3 раз подряд, а цифры, независимо одинаковые или нет, также не повторялись более 3 раз подряд и не более 5 раз во всей строке.

Проверку на латиницу, цифры, дефис сделал, это не сложно, а вот с количеством повторений завис. Очень рассчитываю на Вашу помощь.

С Уважением, Дмитрий.

  Ответить  
 
 автор: Trianon   (29.08.2009 в 23:28)   письмо автору
 
   для: Desh   (29.08.2009 в 23:02)
 

символы подряд отсекаются опережающей (или ретроспективной - дело вкуса) проверкой.
А общее число цифр проще проверить не регулярками, а функцией count_chars()

  Ответить  
 
 автор: Desh   (29.08.2009 в 23:51)   письмо автору
 
   для: Trianon   (29.08.2009 в 23:28)
 

Про функцию count_chars() понял, как-то даже сразу в голову не пришла, большое спасибо)

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

  Ответить  
 
 автор: Trianon   (30.08.2009 в 00:00)   письмо автору
 
   для: Desh   (29.08.2009 в 23:51)
 

как-то так
/^[-a-z0-9]+(?<!.*[0-9]{3}.*)$/

  Ответить  
 
 автор: heed   (30.08.2009 в 04:01)   письмо автору
 
   для: 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]))+$#'
здесь побочный эффект , три дефиса тоже не пройдёт

  Ответить  
 
 автор: Trianon   (30.08.2009 в 09:12)   письмо автору
 
   для: heed   (30.08.2009 в 04:01)
 

точно. Ляпнул.
Но в опережающих могут быть.

  Ответить  
 
 автор: Trianon   (30.08.2009 в 12:47)   письмо автору
 
   для: Trianon   (30.08.2009 в 09:12)
 

$p = '/^((?!.*[\\d]{3}.*)(?!.*?(.)\\2{2}.*)[-a-z0-9]+)$/';

  Ответить  
 
 автор: ride   (31.08.2009 в 10:40)   письмо автору
 
   для: Trianon   (30.08.2009 в 12:47)
 

(?!.*[\\d]{3}.*) поправьте если ошибаюсь: если логин указан верно, первая *, в силу своей жадности, будет каждый раз доходить до конца строки и отступать на прежнее место.

  Ответить  
 
 автор: Trianon   (31.08.2009 в 10:58)   письмо автору
 
   для: ride   (31.08.2009 в 10:40)
 

на самом деле я перемудрил.
достаточно так (?!.*[\\d]{3})
или даже так (?!.*\\d{3})
читается как
(?!     . *    \\d {3}    )

впереди не должно встретиться, после любых символов в любом количестве , цифр подряд в количестве 3 штуки.

А жадность... жадность и вправду можно уменьшить, чтоб производительность не страдала.
(?!.*?\\d{3})

  Ответить  
 
 автор: ride   (31.08.2009 в 11:11)   письмо автору
 
   для: Trianon   (31.08.2009 в 10:58)
 

думаю .* вообще надо убрать.

  Ответить  
 
 автор: Trianon   (31.08.2009 в 11:16)   письмо автору
 
   для: ride   (31.08.2009 в 11:11)
 

Возможно.

  Ответить  
 
 автор: Trianon   (31.08.2009 в 12:00)   письмо автору
 
   для: ride   (31.08.2009 в 11:11)
 

Какой у Вас получился шаблон в конечном итоге?

  Ответить  
 
 автор: ride   (31.08.2009 в 12:59)   письмо автору
 
   для: 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'все ок!';

  Ответить  
 
 автор: Trianon   (31.08.2009 в 13:05)   письмо автору
 
   для: ride   (31.08.2009 в 12:59)
 

попытка ввести любой символ за пределами набора приводит к диагностике "все ок!"

  Ответить  
 
 автор: ride   (31.08.2009 в 13:11)   письмо автору
 
   для: Trianon   (31.08.2009 в 13:05)
 

согласен, не учел это
([-a-z0-9])(?=\d{3}|\1{3}|[^a-z0-9-])

теперь все ок

upd почти))

  Ответить  
 
 автор: Trianon   (31.08.2009 в 13:20)   письмо автору
 
   для: ride   (31.08.2009 в 13:11)
 

$pattern = ?

  Ответить  
 
 автор: ride   (31.08.2009 в 13:33)   письмо автору
 
   для: Trianon   (31.08.2009 в 13:20)
 

тогда еще упрощу
(?=\d{4}|[^a-z0-9-]|(.)\1{3})

  Ответить  
 
 автор: ride   (30.08.2009 в 13:10)   письмо автору
 
   для: heed   (30.08.2009 в 04:01)
 

так с дефисами можно
([a-z0-9])(?=\d{3}|\1{3})

  Ответить  
 
 автор: Desh   (30.08.2009 в 16:22)   письмо автору
 
   для: Desh   (29.08.2009 в 23:02)
 

Большое спасибо за варианты.

Но подошёл вот этот:

$p = '/^((?!.*[\\d]{3}.*)(?!.*?(.)\\2{2}.*)[-a-z0-9]+)$/';

// by Trianon


К сожалению, другие варианты срабатывают не верно или не так как я себе это представляю (возможно, не так описал задачу в первом топе).

P. S. Тут появился вопрос: как можно доработать вышенаписанное регулярное выражение, чтобы дефис не мог повторяться более двух раз подряд?

  Ответить  
 
 автор: Trianon   (30.08.2009 в 18:05)   письмо автору
 
   для: Desh   (30.08.2009 в 16:22)
 

>P. S. Тут появился вопрос: как можно доработать вышенаписанное регулярное выражение, чтобы дефис не мог повторяться более двух раз подряд?

Для этого его следует понять.

  Ответить  
 
 автор: Desh   (30.08.2009 в 18:45)   письмо автору
 
   для: Trianon   (30.08.2009 в 18:05)
 

Честно, абсолютно точно понять выражение не смог, всё же стоит в ближайшее время вникнуть в тему регулярных выражений.

Тем не менее, сделал проверку на двойной дефис подряд с помощью функции strpos(). Если она возвращает значение отличное от нуля, то программа считает, что в строке содержится двойной дефис и приостанавливает работу. Вроде верно.

  Ответить  
 
 автор: heed   (31.08.2009 в 13:48)   письмо автору
 
   для: Desh   (30.08.2009 в 18:45)
 

>значение отличное от нуля
это не то
>strpos() может возвращать как логическое значение FALSE, так и не относящееся к логическому типу значение, которое приводится к FALSE, например, 0

проверяйте на значение FALSE
или такое утверждение (?!.*-{2}) говорит о том что во всей последующей строке не должно быть двух дефисов подряд

// или так (?!.*--)

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования