За последние 24 часа нас посетили 22307 программистов и 1036 роботов. Сейчас ищут 629 программистов ...

Проверка наличия IP-адреса в строке.

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

  1. loxe

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

    С нами с:
    5 сен 2011
    Сообщения:
    30
    Симпатии:
    0
    Помогите составить регулярку по сабжу. Как известно, диапозон IP-адресов с 0.0.0.0 по 255.255.255.255.
     
  2. smitt

    smitt Старожил

    С нами с:
    3 янв 2012
    Сообщения:
    3.166
    Симпатии:
    65
    Получай :)

    Код (PHP):
    1. <span class="syntaxdefault"><br />$str&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxstring">"255.255.255.255"</span><span class="syntaxkeyword">;<br /><br /></span><span class="syntaxdefault">$ip&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">get_ip</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">$str</span><span class="syntaxkeyword">);<br /><br />function&nbsp;</span><span class="syntaxdefault">get_ip</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">$subject</span><span class="syntaxkeyword">){<br /><br /></span><span class="syntaxdefault">$pattern&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxstring">'/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/'</span><span class="syntaxkeyword">;<br /><br />if(</span><span class="syntaxdefault">preg_match</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">$pattern</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">$subject</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">$octets</span><span class="syntaxkeyword">)){<br />&nbsp;&nbsp;&nbsp;&nbsp;for(</span><span class="syntaxdefault">$i</span><span class="syntaxkeyword">=</span><span class="syntaxdefault">1</span><span class="syntaxkeyword">;&nbsp;</span><span class="syntaxdefault">$i</span><span class="syntaxkeyword"><</span><span class="syntaxdefault">5</span><span class="syntaxkeyword">;&nbsp;</span><span class="syntaxdefault">$i</span><span class="syntaxkeyword">++){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(</span><span class="syntaxdefault">$octets</span><span class="syntaxkeyword">[</span><span class="syntaxdefault">$i</span><span class="syntaxkeyword">]&nbsp;<&nbsp;</span><span class="syntaxdefault">0&nbsp;</span><span class="syntaxkeyword">||&nbsp;</span><span class="syntaxdefault">$octets</span><span class="syntaxkeyword">[</span><span class="syntaxdefault">$i</span><span class="syntaxkeyword">]&nbsp;>&nbsp;</span><span class="syntaxdefault">255</span><span class="syntaxkeyword">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;</span><span class="syntaxdefault">FALSE</span><span class="syntaxkeyword">;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />return&nbsp;</span><span class="syntaxdefault">$octets</span><span class="syntaxkeyword">[</span><span class="syntaxdefault">0</span><span class="syntaxkeyword">];<br />}<br />else<br />&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;</span><span class="syntaxdefault">FALSE</span><span class="syntaxkeyword">;<br /><br />}<br />&nbsp;</span><span class="syntaxdefault"></span>
     
  3. Gold Dragon

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

    С нами с:
    30 сен 2012
    Сообщения:
    306
    Симпатии:
    2
    Адрес:
    Тамбов
    так проще и быстрее проверять
    Код (Text):
    1. $str = "255.255.255.255";
    2.  
    3. if (ip2long($str) === false) {
    4.     echo "IP <" . $str . "> плохой";
    5. } else {
    6.     echo "IP <" . $str . "> хороший";
    7. }
    Добавлено спустя 18 минут 25 секунд:
    Код (Text):
    1. $str = "kkk265.255.255.255aaa127.5.3.5sss222.222.33.44";
    2.  
    3. $ip = get_ip($str);
    4.  
    5. function get_ip($str){
    6.  
    7.     $pattern = '#[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}#';
    8.  
    9.     $b = preg_match_all($pattern, $str, $rows);
    10.  
    11.     if($b){
    12.         foreach($rows[0] as $row){
    13.             if (ip2long($row) === false) {
    14.                 echo "IP <" . $row . "> плохой<br>";
    15.             } else {
    16.                 echo "IP <" . $row . "> хороший<br>";
    17.             }
    18.  
    19.         }
    20.     }
    21. }
     
  4. Dmitriy A. Arteshuk

    Dmitriy A. Arteshuk Активный пользователь

    С нами с:
    19 янв 2012
    Сообщения:
    2.445
    Симпатии:
    66
    Адрес:
    Зеленоград
  5. Your

    Your Старожил

    С нами с:
    2 июл 2011
    Сообщения:
    4.074
    Симпатии:
    7
    Тогда уже так:
    Код (PHP):
    1. #[\d]{1,3}.[\d]{1,3}.[\d]{1,3}.[\d]{1,3}#  
    Не надо тут так " \. ".

    И зачем делать лишнюю переменную $b?

    Код (PHP):
    1. if(preg_match_all($pattern,$str,$match)){
    2. } 
    А также лучше всего указать в:
    Код (PHP):
    1. foreach($match as $key => $value) {
    2. } 
     
  6. Gold Dragon

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

    С нами с:
    30 сен 2012
    Сообщения:
    306
    Симпатии:
    2
    Адрес:
    Тамбов
    Экранирую, потому что точка относится к метасимволам
    Затем что считаю (для себя) плохим способом кодинга, когда в условии происходит присвоение: в условии должно быть условие, а не присвоение и сравнение. И при том, а если результат операции понадобится ещё несколько раз.
    Чем лучше, да и зачем? Ты только что выше отказался от создания лишней переменной )))
     
  7. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    какое же там присвоение
     
  8. Gold Dragon

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

    С нами с:
    30 сен 2012
    Сообщения:
    306
    Симпатии:
    2
    Адрес:
    Тамбов
    а что тогда в третьем параметре?
     
  9. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    в третьем параметре мне пофик что =) ибо разговор идёт о возвращаемом значении функции, которое вы за каким-то хреном засовываете в переменную, которая будет использована лишь единожды.

    Это у вас какие-то глубинные страхи.

    Однако я тоже против присвоений в условиях. Просто это не тот случай.
     
  10. Gold Dragon

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

    С нами с:
    30 сен 2012
    Сообщения:
    306
    Симпатии:
    2
    Адрес:
    Тамбов
    Ну так я ради этого случая не буду же ведь менять свой стиль и свои принципы ))) Это всего-лишь маленький кусочек кода, мало ли как он будет дальше развиваться... ;) Да и код лучше читается когда всё отдельно и по порядку

    А вот что касается "пофик", то именно третий параметр в дальнейшем используется и именно там создаётся массив $rows и туда всё складывается )))
     
  11. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    твой принцип не относится к такому случаю. Скорее всего у тебя некое нечёткое понимание и недоверие к тому, как работают функции. Это уже не принцип.

    это функция пхп. она НИКАК не будет дальше развиваться. Она возвращает значение как написано в документации. Ты боишься возвращаемого значения, т.к. один из аргументов передаётся по ссылке.
     
  12. Gold Dragon

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

    С нами с:
    30 сен 2012
    Сообщения:
    306
    Симпатии:
    2
    Адрес:
    Тамбов
    я бесстрашен ))))) Подведём итог: можно делать так, а можно делать так...
     
  13. Your

    Your Старожил

    С нами с:
    2 июл 2011
    Сообщения:
    4.074
    Симпатии:
    7
    Шаблон смотри.

    В php переменная это объект.
    Функция тем более возвращает "глобальную названную переменную массивом, когда выполнится", переменная указанная 3 параметром будет доступна ниже другого кода.
    Никакой нет выгоды создавать опять переменную.
    О каких может быть речь других применений, я не врубился)

    Быстрее проходит и выводит ключ и значение.
    Тем более массив передаешь с числовыми ключами.
     
  14. Gold Dragon

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

    С нами с:
    30 сен 2012
    Сообщения:
    306
    Симпатии:
    2
    Адрес:
    Тамбов
    Your, да уж подвели итог ))) можно так, можно по другому, где дело вкуса, где привычки, а где и "общепринятым" ..

    Проверял? ;) Завтра, если будет время, протестирую.. а то как-то не верится =)
     
  15. Gold Dragon

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

    С нами с:
    30 сен 2012
    Сообщения:
    306
    Симпатии:
    2
    Адрес:
    Тамбов
    Your, возвращаюсь к твоему коду.. То ли я туплю, то ли что-то делаю не то

    Этот код foreach ($rows[0] as $value) возвращает это
    Код (Text):
    1. string(15) "265.255.255.255"
    2. string(9) "127.5.3.5"
    3. string(13) "222.222.33.44"
    А вот это foreach ($rows as $key => $value) возвращает это
    Код (Text):
    1. array(3) {
    2.   [0]=>string(15) "265.255.255.255"
    3.   [1]=>string(9) "127.5.3.5"
    4.   [2]=>string(13) "222.222.33.44"
    5. }
    Так что это наверное не приемлемо тут, если только писать так
    foreach ($rows[0] as $key => $value)
    Но это вариант работает медленнее, на считанные миллисекунды, но медленнее
     
  16. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    в пхп счёт идёт на микросекунды, и задумываться о них не стоит.
     
  17. Gold Dragon

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

    С нами с:
    30 сен 2012
    Сообщения:
    306
    Симпатии:
    2
    Адрес:
    Тамбов
    да это понятно. Вопрос был о приемлемости кода. А вот если получать и ключ и значение, то при объёме в миллион записей на это потратиться больше примерно на 0,1-0,15 секунды (это по моим расчётам). Это вообще ничто, но я точно знаю теперь что проход медленнее, т.к. лично проверил )))
     
  18. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    согласен. просто пхп такой быстрый, что прям я восхищаюсь. =)
     
  19. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    регулярка которая проверяет и диапазоны элементов IP адреса.
    тоесть не пропустит некорректные адреса типа 256.958.210.25
    Код (Text):
    1. ^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$
     
  20. Gold Dragon

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

    С нами с:
    30 сен 2012
    Сообщения:
    306
    Симпатии:
    2
    Адрес:
    Тамбов
    runcore, регулярка это очень медленный механизм, и если в ней много условий, то это только хуже. Если есть альтернативные функции, то нужно пользоваться ими
     
  21. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    допустим есть текст в котором встречаются ip адреса. нужно выдрать из него все КОРРЕКТНЫЕ.
    какие альтернативные варианты вы предложите, чтобы они были быстрее одной регулярки?
    помимо скорости выполнения парсинга - немаловажно еще время потраченное на решение задачи.
    я напишу регулярку за пару минут и все - ЗАДАЧА решена!
    вы будете писать весь парсинг вручную, перебирать варианты, искать наиболее быстрый - в итоге выиграете пару микросекунд всего, зато потратите НЕДЕЛЮ. я за это время успею сделать в 10 раз больше другой работы - и заработать на этом, соответсвенно.
    не стоит забывать об этом.

    и не нужно вешать лапшу про тормознутость регулярок. они работают очень быстро, если уметь их писать.
    неверите? устройте тестирование. результаты вас удивят!
     
  22. Gold Dragon

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

    С нами с:
    30 сен 2012
    Сообщения:
    306
    Симпатии:
    2
    Адрес:
    Тамбов
    Не верю. Слова, слова, слова. Уже ни раз на этом форуме слышу подобное, но никто не прикладывает результаты тестирования. А я вот не ленюсь и тестирую. И очень часто бывает что оппонент не прав оказывается.

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

    Добавлено спустя 9 минут 22 секунды:
    кстати, runcore, где-то ошибка в твоей регулярки.
    к примеру, 265.22.22.22 пропустит, но преобразует в 65.22.22.22

    Добавлено спустя 27 минут 58 секунд:
    А вот теперь с уверенностью могу сказать, что регулярка runcore эффективнее (при условии если исправить ошибку) =)

    Вот тест
    Код (PHP):
    1. <?php
    2. $a = '';
    3. $str = "kkk165.355.255.255aaa127.5.3.5sss222.222.33.44skds132.123.1.1w";
    4. for ($i = 0; $i < 50000; $i++) {
    5.     $a .= $str;
    6. }
    7. $str = $a;
    8.  
    9. $pattern1 = '#[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}#';
    10. $pattern2 = '#((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)#';
    11.  
    12. //**************************************************
    13. $start = microtime(true);
    14. preg_match_all($pattern1, $str, $rows);
    15. foreach ($rows[0] as $row) {
    16.     if (ip2long($row) !== false) {
    17.         $a = $row;
    18.     }
    19. }
    20. echo round((microtime(true) - $start), 5);
    21.  
    22. echo '<hr>';//**************************************************
    23.  
    24. $start = microtime(true);
    25. preg_match_all($pattern2, $str, $rows);
    26. foreach ($rows[0] as $row) {
    27.         $a = $row;
    28. }
    29. echo round((microtime(true) - $start), 5);
    30.  
    31. //************************************************** 
    а вот результат
    значение $i = 1000
    первый вариант - 0.14503
    второй вариант - 0.02137

    значение $i = 10000
    первый вариант - 1.34146
    второй вариант - 0.22293

    значение $i = 50000
    первый вариант - 6.76594
    второй вариант - 1.16916
     
  23. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    Регулярки оч быстрые. Вобще пхп очень быстрый. И хватит экономить ресурсы компа. Пока нет нагрузки в миллион посетителей хватит из себя воображать фейсбук! :)
     
  24. Gold Dragon

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

    С нами с:
    30 сен 2012
    Сообщения:
    306
    Симпатии:
    2
    Адрес:
    Тамбов
    конечно :) Главное их с умом делать, а то можно просто всё убить одним махом... А с другой стороны, ты увидел два варианта решения и увидел результаты тестов, и хоть это и милли(микро), но выберешь который шустрее )))))
     
  25. Your

    Your Старожил

    С нами с:
    2 июл 2011
    Сообщения:
    4.074
    Симпатии:
    7
    Проверь на 100 000 - 1000 000 элементов. =)