За последние 24 часа нас посетили 17278 программистов и 1231 робот. Сейчас ищут 1243 программиста ...

Грамотное регулярное выражение

Тема в разделе "Регулярные выражения", создана пользователем Elkaz, 5 янв 2008.

  1. Elkaz

    Elkaz Старожил
    Команда форума Модератор

    С нами с:
    26 июн 2006
    Сообщения:
    3.373
    Симпатии:
    0
    Адрес:
    Баку, Азербайджан
    С этим пока проблемы...
    Регулярки (синтаксис) только-только начал изучать по статьям Бородина и Сергея Колесниченко.
    Задача такая. Профильтровать переменную $name на следущее:
    Разрешены: русский алфавит, английский алфавит (но что бы не смешивались англ. и русс.), тильда "~", нижнее подчеркивание, пробел, восклицательный знак.

    Долго мучаюсь :)
     
  2. antonn

    antonn Активный пользователь

    С нами с:
    10 июн 2007
    Сообщения:
    2.996
    Симпатии:
    0
    что то типа
    Код (Text):
    1. #^(([а-я]|[a-z])[\~_ \!])$#i
    не помню, правильно ли задал интервал русских букв и не помню, как правильно записывается пробел (s чего то там), нет под рукой мануалов %)
     
  3. Elkaz

    Elkaz Старожил
    Команда форума Модератор

    С нами с:
    26 июн 2006
    Сообщения:
    3.373
    Симпатии:
    0
    Адрес:
    Баку, Азербайджан
    antonn
    PHP:
    1.  
    2. <?php
    3. $name = 'lose';
    4. if (!preg_match("/^(([а-я]|[a-z])[\~_\s\!])$/i", $name)) echo 'Wrong';
    5. else echo 'Correct';
    6. ?>
    7.  
    Выводит Wrong.
    Символ пробела - \s
    Интервал русских букв правильно задан :)

    Мне так кажется, ошибка где-то здесь: [\~_\s\!]
    P.s
    Скорее всего из-за условия.
    Т.к $name не обязательно должен содержать тильду, подчеркивание пробел и т.д. Просто они НЕ запрещены:)
     
  4. Ti

    Ti Активный пользователь

    С нами с:
    3 июл 2006
    Сообщения:
    2.378
    Симпатии:
    1
    Адрес:
    d1.ru, Екатеринбург
    дополню предыдущего оратора:
    PHP:
    1. <?
    2. function test($string) {
    3.     $word = '([а-я]+|[a-z]+)'; // регулярко на слово
    4.     $separator = '[~_ !]'; // на разделитель слова
    5.     $re = "#^$word($separator+$word)*$#"; // минимум, подопытный должен содержать слово. Разделенные не меньше одним разделителем, могут быть еще слова.
    6.     $re .= 'i'; // любой регистр
    7.     $re .= 'u'; // строки в UTF-8
    8.     return (bool) preg_match($re, $string);
    9. }
    10.  
    11. // ну и "парачка" тестов что это действительно так:
    12.  
    13. $goodList = array(
    14.     'w',
    15.     'waka',
    16.     'waka waka',
    17.     'я',
    18.     'криведка',
    19.     'и порвилукракадилу',
    20.     'ну и с англицкими словами waka вот',
    21.     'разделителей_может!быть !~_ много',
    22.     'а СлоВа моГут имеТь ЛюбоЙ РЕГИСТР',
    23. );
    24.  
    25. foreach ($goodList as $string) if (!test($string)) echo $string,'<br />';
    26.  
    27. $blackList = array(
    28.     '',
    29.     ' ',
    30.     'wakaсрусским',
    31.     'неправильный#разделитель',
    32.     'неправильный # разделитель_с_пробелом',
    33.     ' почему в начале и в конце разделители ',
    34. );
    35.  
    36. foreach ($blackList as $string) if (test($string)) echo $string,'<br />';
    37.  
    38. /*
    39.     результат - список не прошедших проверку строк
    40.     у меня пусто, а у Вас?
    41. */
     
  5. Elkaz

    Elkaz Старожил
    Команда форума Модератор

    С нами с:
    26 июн 2006
    Сообщения:
    3.373
    Симпатии:
    0
    Адрес:
    Баку, Азербайджан
    Ti
    Угу, это уже лучше :) Спасибо за расширенный пример.
    Но тогда не проходят строки вида:
    !Ti!
    _TI_

    А как мы знаем, пользователи любят приукрашить свои ники... :(
    PHP:
    1.  
    2. <?php
    3. function test($string) {
    4.      
    5.      $word = '([а-я]+|[a-z]+)'; // регулярко на слово
    6.      $separator = '[~_ !]'; // на разделитель слова
    7.     $re = "#^$separator+$word($separator+$word)+$separator*$#"; // минимум, подопытный должен содержать слово. Разделенные не меньше одним разделителем, могут быть еще слова.
    8.      $re .= 'i'; // любой регистр
    9.      $re .= 'u'; // строки в UTF-8
    10.      $string = trim ($string); // убираем лишние пробелы слева и справа
    11.      return (bool) preg_match($re, $string);
    12.  }
    13. ?>
    14.  
    Насколько правильно я думаю? :)
     
  6. Ti

    Ti Активный пользователь

    С нами с:
    3 июл 2006
    Сообщения:
    2.378
    Симпатии:
    1
    Адрес:
    d1.ru, Екатеринбург
    вы обязали (+) "украшать" начало первого слова
    и обязали использовать больше одного слова

    PHP:
    1. <?
    2. $re = "#^$separator*$word($separator+$word)*$separator*$#";
    что бы быть уверенным, напишите проверки на все случаи
     
  7. Elkaz

    Elkaz Старожил
    Команда форума Модератор

    С нами с:
    26 июн 2006
    Сообщения:
    3.373
    Симпатии:
    0
    Адрес:
    Баку, Азербайджан
    Ti
    Большое спасибо. Все работает.
     
  8. Ti

    Ti Активный пользователь

    С нами с:
    3 июл 2006
    Сообщения:
    2.378
    Симпатии:
    1
    Адрес:
    d1.ru, Екатеринбург
    PHP:
    1. <?
    2. function test($string) {
    3.     $separator = '[~_ !]'; // на разделитель слова
    4.  
    5.     // выражение на русском
    6.     $word = '[а-я]+';
    7.     $ru = '$separator*$word($separator+$word)*$separator*';
    8.  
    9.     // выражение на английском
    10.     $word = '[a-z]+';
    11.     $en = '$separator*$word($separator+$word)*$separator*';
    12.  
    13.     $re = "#^($ru|$en)$#";
    14.     $re .= 'i'; // любой регистр
    15.     $re .= 'u'; // строки в UTF-8
    16.     $string = trim ($string); // убираем лишние пробелы слева и справа
    17.     return (bool) preg_match($re, $string);
    18. }
    19. // требует проверок
    20.  
     
  9. Elkaz

    Elkaz Старожил
    Команда форума Модератор

    С нами с:
    26 июн 2006
    Сообщения:
    3.373
    Симпатии:
    0
    Адрес:
    Баку, Азербайджан
    Ti
    Проверку не прошел весь Good List :)
     
  10. Ti

    Ti Активный пользователь

    С нами с:
    3 июл 2006
    Сообщения:
    2.378
    Симпатии:
    1
    Адрес:
    d1.ru, Екатеринбург
    в таком случае можно поступить гораздо проще:
    PHP:
    1. <?
    2. function test($string) {
    3.     $separator = '~_ !'; // на разделитель слова
    4.     $re = "#^([а-я$separator]+|[a-z$separator]+)$#";
    5.     $re .= 'i'; // любой регистр
    6.     $re .= 'u'; // строки в UTF-8
    7.     $string = trim ($string); // убираем лишние пробелы слева и справа
    8.     return (bool) preg_match($re, $string);
    9. }
     
  11. Ti

    Ti Активный пользователь

    С нами с:
    3 июл 2006
    Сообщения:
    2.378
    Симпатии:
    1
    Адрес:
    d1.ru, Екатеринбург
    естественно - условия другие, меняйте оба листа проверок в соответствии с условиями
     
  12. Elkaz

    Elkaz Старожил
    Команда форума Модератор

    С нами с:
    26 июн 2006
    Сообщения:
    3.373
    Симпатии:
    0
    Адрес:
    Баку, Азербайджан
    Ti
    Вот теперь действительно все :)
    Не прошли проверку:

    ну и с англицкими словами waka вот
    -Hello-
    Good Ангел
    True программист

    Спасибо.
     
  13. antonn

    antonn Активный пользователь

    С нами с:
    10 июн 2007
    Сообщения:
    2.996
    Симпатии:
    0
    фигасе вы тут флудите :)
    че паритесь то? :)
    Код (Text):
    1. function check_name($string){
    2.   if(preg_match("#^([a-z\~\s\!_])$#i", $string)){
    3.       result:=true;
    4.   }elseif(preg_match("#^([а-я\~\s\!_])$#i", $string)){
    5.      result:=true;
    6.   }else{
    7.     result:=false;
    8.   }
    9. }
     
  14. Anonymous

    Anonymous Guest

    antonn, эт че, дельфи?
     
  15. antonn

    antonn Активный пользователь

    С нами с:
    10 июн 2007
    Сообщения:
    2.996
    Симпатии:
    0
    ой, там return нужно, зарапортавался %)
     
  16. Ti

    Ti Активный пользователь

    С нами с:
    3 июл 2006
    Сообщения:
    2.378
    Симпатии:
    1
    Адрес:
    d1.ru, Екатеринбург
    antonn
    1. Опять забыли квантификатор +
    2. Написали тоже самое
     
  17. antonn

    antonn Активный пользователь

    С нами с:
    10 июн 2007
    Сообщения:
    2.996
    Симпатии:
    0
    про плюс ничего не сказано, может ему нравится когда имя из нуля символов :)