forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   PHP / MySQL (http://forum.boolean.name/forumdisplay.php?f=135)
-   -   Готовим регулярные выражения: Проверка строки по шаблону (http://forum.boolean.name/showthread.php?t=15774)

Randomize 04.11.2011 23:23

Готовим регулярные выражения: Проверка строки по шаблону
 
Вечер добрый, мои дорогие пекари.
Сегодня я решил окунуть вас с головой в такую часто вызывающую у многих головную боль тему как "Регулярные выражения".
Кто не в курсе эта такой особый способ работы с текстом. И применений ему масса. И эту массу для наполнения ваших булочек мы сегодня будем разбирать по составу :B

Сегодня мы будем проверять строку по шаблону.

Вам понадобится:
Онлайн тестер регулярных выражений
http://www.functions-online.com/preg_match.html
Как юзать под оффтопом:

subject - наш вводимый текст
pattern - наше выражение
flags и offset пока не трогаем.

В результате выполнения нас пока что интересует только result.
Он булевой:
1 - строка валидна
0 - строка не валидна


Или использовать вот такое на своём веб сервере:
PHP код:

<?
$pattern = (isset($_POST['pattern'])) ? $_POST['pattern'] : '';
$subject = (isset($_POST['subject'])) ? $_POST['subject'] : '';
$pattern = stripslashes($pattern);
$subject = stripslashes($subject);
?>
<hr />
<form action ="" method="post">
    Pattern:
    <input style="width: 370px; padding: 5px;" name="pattern" type="text" value="<?= $pattern?>" /><br />
    Subject:
    <textarea style="width: 370px; padding: 5px;" cols="20" rows="10" name="subject"><?= $subject?></textarea>
    <input type="submit" value="Выполнить" />
</form>

<?= (@preg_match($pattern$subject)) ? 'Да' 'Неа'?>




И так - без вступительных речей.
Начнём по мужски сразу в лоб:
/^http(s?):\/\/[a-z0-9-.]+(:[0-9]+)?(\/(.*))?$/i
Да это же похоже на:
私の馬を見て、私の馬は素晴らしいです!

Первое, что бросается в глаза это http. Угу, значит речь идёт об URL.

Для начала давайте подумаем из чего же состоит URL и каких видов они бывают.
* Нас на данный момент интересуют только http.

Стандартный вид:
http://domain.tld/dir/script.ext

Тоже самое но с добавлением защищённого(http) соединения:
https://domain.tld/dir/script.ext

Так же в URL может быть указан порт вот таким образом:
https://domain.tld:7777/dir/script.ext

Давайте пометим части цветами:

https://domain.tld:7777/dir/script.ext

И легенда.
¦ - префикс "s" для зашифрованного соединения (не обязателен)
¦ - доменное имя
¦ - порт (не обязателен)
¦ - путь после домена (не обязателен)

Ну что, господа, уже представили себе как это реализовывать на всяких такм strpos substr и тд? Сложно, да? А на регулярках это займёт 1 строку.

Давайте продумаем алгоритм.
1) Проверка есть ли в начале http если нет, то стоп.
2) Существует ли приставка "s" к http? Есть - оставляем, нет - фиг с ним едем дальше.
3) Введён ли домен используя сиволы a-z 0-9 точка и дефиз(русские домены пока не берём) есть? идём дальше - иначе стоп.
4) Введён ли порт? Начинается с ":" и далее только цифры 0-9 и их сколько угодно (на самом деле нет, но мы же только начинаем).
5) Есть "/"? Если да то пофигу и если нет тоже :D Но проверить надо дабы понять где кончается домен а где там начинается путь.

Теперь к делу - собираем регулярку!
Стройка начинается с сортира, а регулярка с границ выражения.

Цитата:

Сообщение от Регулярочка
/^...$/

/ - управляющий символ. Им обрамляется всё выражение целиком.
^ - старт строки.
$ - конец строки.

Дальше прямым текстом пишем что в начале строки должен быть http:

Цитата:

Сообщение от Регулярочка
/^http$/

Через такое выражение пройдёт только фраза "http".

Общие понятия по под-выражениям и диапазонам/наборам символов:
[...] - диапазон или набор символов.
Например:
[a-z] - 1 символ, который может принимать значения от a до z
[0-9] - 1 символ, который может принимать значения от 0 до 9
[0-9a-z] - 1 символ, который может принимать значения от 0 до 9 или от a до z
[0-9a-zA-Z] - 1 символ, либо любая буква англ. алфавита либо любая 1 цифра
[ab12] - 1 символ, который может принимать значения a,b,1,2 но никакие другие

Диапазон в развёрнутом виде и с 1 вариантом пишется без скобок, хотя никто не запрещает писать в скобках например так:
[a][s][s]

Для указания любого произвольного символа используется точка "."
Это делается так "[.]" или проще так "."
Например:
[.о.о.] под него подпадут слова "солод", "молод"

Так же мы можем указывать для таких диапазонов количество вхождений:
[а] - 1 буква "а"
[а]+ - 1 и более буква "a"
[a]* - сколько угодно "а" и нисколько тоже
[а]{3} - 3 буквы "а"
[а]{3,} - 3 и более букв "а"
[а]{1, 12} - от 1 до 12 букв "а"

Получается, что:
[a]* эквивалентен [a]{0,}
[a]+ эквивалентен [a]{1,}
[a]? эквивалентен [a]{0,1}


() - подвыражение. Нужно для группирования наборов символов внутри основного выражения.
Например:
([a-z][A-Z][0-9]) - говорит о том что тут 3 символа буква в нижнем регистре, буква в верхнем, цифра
Так же такие подвыражения будут возвращены в результат ф-ции ($matches)

Флаги для выражений или диапазонов (ставить после):
+ - выражение может повторяться от 1 до скольки угодно раз
? - это выражение может отсутствовать (т.е. если нет такого вхождения то нет)
{число} - это выражение повторяется указаное число раз. Так же можно указать диапазон например {2-3}
* - это выражение повторяется сколько угодно раз и может не быть вовсе


Теперь добавим первое условие - наличие "s"
(..)-подвыражение
? - флаг внутри выражения, говорящий о том что соблюдение не обязательно

Цитата:

Сообщение от Регулярочка
/^http(s?)$/

Тут уже пройдёт "http" и "https".
Теперь нам надо добавить "://" если c ":" всё в порядке, то с символом / уже нет - он управляющий! Его надо экранировать.
Это делается так: "\/\/" что равнозначно: "//"

Цитата:

Сообщение от Регулярочка
/^http(s?):\/\/$/

Далее домен: Буквы от a-z цифры 0-9, тире и точка и их в общей сложности может быть сколько угодно.
[a-z0-9-.]+

Цитата:

Сообщение от Регулярочка
/^http(s?):\/\/[a-z0-9-.]+$/

Символ плюса на конце диапазона говорит что выражение может повторяться от 1 до скольки угодно раз.
Теперь ссылки вида:
http://boolean.name
https://boolean.name
https://boo.le-an.na-me
Пройдут проверки. Слеш на конце, кстати, обломает проверку ведь его нигде не ждут :B

Теперь порт. В начала уже знакомый нам ":" потом некоторое кол-во цифр:
(:[0-9]+)?
Разберём скобку.
( - начало подвыражения
: - нужный для порта символ двоеточия
[0-9] - этот диапазон символов, в данном случае нас интересуют только цифры
+ - Указывает количество вхождений - сколько угодно раз, но не меньше 1го символа
) - конец подвыражения
? - это подвыражение не обязательно

Цитата:

Сообщение от Регулярочка
/^http(s?):\/\/[a-z0-9-.]+(:[0-9]+)?$/

Отлично! Теперь у нас спокойно пролезают:
https://domain.tld:8080
http://dom-ain.tld
https://domain.gov.ua.tld:113

Теперь завершающий этап - всё что после слеша:

(
\/ - наш заветный слеш
(.*) - всё что угодно (даже ничего) и сколько угодно
)? - всё подвыражение не обязательно

Цитата:

Сообщение от Регулярочка
/^http(s?):\/\/[a-z0-9-.]+(:[0-9]+)?(\/(.*))?$/

Теперь через наше выражение пройдёт уже почти любой url:

http://domain.tld/newthread.php?do=postthread
https://domain.tld/newthread.php?do=postthread
http://domain.tld:80/newthread.php?do=postthread

Осталось пофиксить последний изъян. Наше выражение чувствительно к регистру. Это легко исправить добавив в самый конец глобальный флажок i.
Вот так:
Цитата:

Сообщение от Регулярочка
/^http(s?):\/\/[a-z0-9-.]+(:[0-9]+)?(\/(.*))?$/i

Вот и всё.

Чего не хватает:
1) Проверки что в домене есть хотя бы одна буква кроме точки или тире
2) Лимит на количество цифр в порте.


Спасибо вам за уделённое время и удачных экспериментов. Если дело пойдёт - будет вам вторая часть.

ABTOMAT 04.11.2011 23:56

Ответ: Готовим регулярные выражения: Проверка строки по шаблону
 
Я всё понял! Хороший урок.
Look at my horse, my horse is amazing!

baton4ik 04.11.2011 23:57

Ответ: Готовим регулярные выражения: Проверка строки по шаблону
 
Легко читаемая и понятная мини-статья, спасибо.

Цитата:

私の馬を見て、私の馬は素晴らしいです!
http://www.youtube.com/watch?v=_RjMSWhGWak


Цитата:

PHP код:

/^http(s?)://$/ 

Далее домен: Буквы от a-z цифры 0-9, тире и точка и их в общей сложности может быть сколько угодно.
[a-z0-9-.]+
Тут, очевидно, имелось в виду /^http(s?):\/\/$/ ?

Randomize 05.11.2011 00:06

Ответ: Готовим регулярные выражения: Проверка строки по шаблону
 
Цитата:

Сообщение от baton4ik (Сообщение 208406)
Легко читаемая и понятная мини-статья, спасибо.
Тут, очевидно, имелось в виду /^http(s?):\/\/ ?

Ой! Булочный тег [ php] навёл марафет.

VotapilD 05.11.2011 15:26

Ответ: Готовим регулярные выражения: Проверка строки по шаблону
 
Наконец-то я увидел правильный порядок разбора *_* Спасибо, а то. когда нужно было - путался постоянно =(
Лошадь и вправду прекрасна %)

Randomize 06.11.2011 00:33

Ответ: Готовим регулярные выражения: Проверка строки по шаблону
 
Принимаются предложения тем для следующей статейки.

moka 06.11.2011 00:42

Ответ: Готовим регулярные выражения: Проверка строки по шаблону
 
JSON

.Squid 06.11.2011 00:50

Ответ: Готовим регулярные выражения: Проверка строки по шаблону
 
Цитата:

Сообщение от MoKa (Сообщение 208522)
JSON

Я, честно говоря, не знаю, что о нем можно написать. Вроде как очень простой формат (не путать с "не функциональный") - из Википедии можно все понять.
Но если будет хорошая статья, то я за.

moka 06.11.2011 01:30

Ответ: Готовим регулярные выражения: Проверка строки по шаблону
 
Многие не совсем понимают его плюсов. И используют частенько совсем не по назначению.

Если статью направить на описание плюсов в использовании например с точки зрения скорости разработки, и удобства, используя серверную часть на PHP или даже собственный (WebSockets протокола), то статья имеет потенциал.

Сейчас сильно развивается направление WebSockets, а как мы знаем, юзается JavaScript, и JSON в данном случае - готовое решение для сериализации.
Рассмотрение этого формата с этой точки зрения, потенциально.

Формат простой, и для тех кто смышлённый, статьи не нужны. А те кто читает статьи, нуждается в разъяснениях, это отличный момент, когда можно качественно "промыть" и направить мышление у начинающих..

.Squid 06.11.2011 02:12

Ответ: Готовим регулярные выражения: Проверка строки по шаблону
 
Ну тогда я бы на месте автора привел несколько примеров использования вне веб-разработки. Для геймдева этот формат имхо лучше, чем XML. И не только для хранения конфигураций, но и даже для текстовых форматов медии. Ребята из bitsquid его нахваливают.

moka 06.11.2011 02:16

Ответ: Готовим регулярные выражения: Проверка строки по шаблону
 
Есть даже NoSQL базы данных, построенные на подобных структурах: ключ : значение, а не таблицах..

ABTOMAT 27.06.2012 05:17

Ответ: Готовим регулярные выражения: Проверка строки по шаблону
 
Только что эта статья спасла мою жопу на работе.
Ещё раз респект!

Trazzy 14.03.2013 19:34

Ответ: Готовим регулярные выражения: Проверка строки по шаблону
 
Есть такое выражение:
^([0-9а-z]+)$

использую в htaccess таким образом:
RewriteEngine On
RewriteRule ^([0-9а-z]+)$ page.php?go=$1 [L]

в общем все, что совпадает с этим выражением передается в виде GET-запроса странице pаge.php

Вопрос: как сделать обратную этому функцию? То есть чтобы все остальное попадало на другую страницу.

З.Ы. я так понял в регулярках нет такой вещи как NOT или я ошибаюсь?

Randomize 14.03.2013 20:22

Ответ: Готовим регулярные выражения: Проверка строки по шаблону
 
Цитата:

Сообщение от 2Fake (Сообщение 254896)
Есть такое выражение:
^([0-9а-z]+)$

использую в htaccess таким образом:
RewriteEngine On
RewriteRule ^([0-9а-z]+)$ page.php?go=$1 [L]

в общем все, что совпадает с этим выражением передается в виде GET-запроса странице pаge.php

Вопрос: как сделать обратную этому функцию? То есть чтобы все остальное попадало на другую страницу.

З.Ы. я так понял в регулярках нет такой вещи как NOT или я ошибаюсь?

Используй отрицания:
RewriteRule ^([^0-9^a-z]+)$ other.php?go=$1 [L]

^0-9 - не цифры
^a-z - не буквы
^sosiska - не сосиска

Trazzy 14.03.2013 21:59

Ответ: Готовим регулярные выражения: Проверка строки по шаблону
 
То что надо.
Thnx! (особенно за сосиску) :)

den 21.03.2013 00:14

Ответ: Готовим регулярные выражения: Проверка строки по шаблону
 
Как сделать такую регулярку, что-то не соображу:
либо одна буква z ( z ), либо несколько цифр ( \d+ )

Randomize 21.03.2013 00:36

Ответ: Готовим регулярные выражения: Проверка строки по шаблону
 
Цитата:

Сообщение от Den (Сообщение 255407)
Как сделать такую регулярку, что-то не соображу:
либо одна буква z ( z ), либо несколько цифр ( \d+ )

Например так:
Код:

/^([z]|[\d]+)$/
"|" - воспринимается как "или"

Reizel 23.03.2013 03:06

Ответ: Готовим регулярные выражения: Проверка строки по шаблону
 
Подскажите, какую регулярку замутить, чтоб из HTML-выдачи выдрать все ссылки(<a></a>) ?

moka 23.03.2013 03:18

Ответ: Готовим регулярные выражения: Проверка строки по шаблону
 
Цитата:

Сообщение от Reizel (Сообщение 255547)
Подскажите, какую регулярку замутить, чтоб из HTML-выдачи выдрать все ссылки(<a></a>) ?

Учись пользоваться гуглом (первая ссылка):
http://lmgtfy.com/?q=extract+url+from+html+regex

Randomize 24.03.2013 22:37

Ответ: Готовим регулярные выражения: Проверка строки по шаблону
 
Цитата:

Сообщение от Reizel (Сообщение 255547)
Подскажите, какую регулярку замутить, чтоб из HTML-выдачи выдрать все ссылки(<a></a>) ?

Например http://ideone.com/oQvJK1

Черный крыс 29.09.2013 14:28

Ответ: Готовим регулярные выражения: Проверка строки по шаблону
 
А не лучше будет так ? ->

PHP код:

/^http(s)?$/ 


Phantom 29.09.2013 23:08

Ответ: Готовим регулярные выражения: Проверка строки по шаблону
 
Как-то давно написал такой скрипт для парсинга ссылок с любого сайта. Там есть регулярка, кроме того, скрипт позволяет написать любую свою регулярку и выдрать с нужной страницы что-то ещё.

Ещё тогда же написал более продвинутый парсер, чисто для ссылок, он раскрывает относительные ссылки, а из названия ссылок удаляет html теги (поэтому некоторые ссылки могут не иметь названия, если ссылка имеет вид картинки, например).

Оба скрипта определяют кодировку страницы и результат выводят в utf-8, конвертируя если требуется.

Цитата:

Сообщение от Diablo1909 (Сообщение 267813)
А не лучше будет так ? ->

PHP код:

/^http(s)?$/ 


Ссылки бывают относительными и не только http/https

Phantom 29.09.2013 23:56

Ответ: Готовим регулярные выражения: Проверка строки по шаблону
 
Только что немного усовершенствовал скрипты, могли быть глюки с кодировкой и т. п. Кто попал на глюки, можете заценить снова. =)

Жека 05.06.2014 06:37

Ответ: Готовим регулярные выражения: Проверка строки по шаблону
 
Чтобы не создавать новую тему, пишу тут.
Прикольная штукенция: http://regexcrossword.com

Nikich 05.06.2014 12:56

Ответ: Готовим регулярные выражения: Проверка строки по шаблону
 
О парсинге HTML с помощью RexEx, может быть, кто-то не видел:
http://stackoverflow.com/questions/1...732454#1732454

ABTOMAT 13.12.2014 17:44

Ответ: Готовим регулярные выражения: Проверка строки по шаблону
 
Вопрос для уточнения:

Цитата:

* - это выражение повторяется сколько угодно раз и может не быть вовсе

+ - Указывает количество вхождений - сколько угодно раз, но не меньше 1го символа
То есть + отличается от * только тем, что + обязательно хотя бы одно вхождение, если ноль то + не сработает. * же срабатывает и при нуле вхождений. В остальном всё то же самое. Верно понимаю?

Randomize 13.12.2014 17:47

Ответ: Готовим регулярные выражения: Проверка строки по шаблону
 
Цитата:

Сообщение от ABTOMAT (Сообщение 290589)
То есть + отличается от * только тем, что + обязательно хотя бы одно вхождение, если ноль то + не сработает. * же срабатывает и при нуле вхождений. В остальном всё то же самое. Верно понимаю?

Именно так.

Alex3636 24.08.2018 23:32

второго урока не будет?:)

ABTOMAT 25.08.2018 00:36

Ответ: Готовим регулярные выражения: Проверка строки по шаблону
 
Цитата:

Сообщение от Alex3636 (Сообщение 315509)
второго урока не будет?:)

Увы, скорее всего нет. Автор занялся зарабатыванием денег.
Но ты можешь задавать вопросы здесь, он заходит почитать иногда.

Randomize 27.08.2018 02:05

Ответ: Готовим регулярные выражения: Проверка строки по шаблону
 
Цитата:

Сообщение от Alex3636 (Сообщение 315509)
второго урока не будет?:)

Есть какой-то конкретный момент, который интересует?


Часовой пояс GMT +4, время: 08:18.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot