Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Тексты > необязательная часть регулярки


Автор: gta4kv 14.4.2008, 21:44
всем доброй ночи. в регулярках как не варил, так и не варю)

есть регулярка:

Код

"#\[youtube\]http:\/\/(ru|tw|jp|kr|au|br|ca|de|es|fr|ie|it|mx|nl|nz|pl|ul|.)youtube.com\/watch[?]v=([a-zA-Z0-9-_.=]+)\[/youtube\]#is"


как сделать что бы поддомен был не обязателен? Т.е можно и ru.youtube.com и просто youtube.com?

заранее благодарен

Автор: Sannis 14.4.2008, 21:53
Доброй.

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

"#\[youtube\]http://((ru|tw|jp|kr|au|br|ca|de|es|fr|ie|it|mx|nl|nz|pl|ul)\.){0,1}youtube.com\/watch[?]v=([a-zA-Z0-9-_.=]+)\[/youtube\]#is"
или
Код

"#\[youtube\]http://(ru\.|tw\.|jp\.|kr\.|au\.|br\.|ca\.|de\.|es\.|fr\.|ie\.|it\.|mx\.|nl\.|nz\.|pl\.|ul\.|)youtube.com\/watch[?]v=([a-zA-Z0-9-_.=]+)\[/youtube\]#is"
Слеши в http:// нужно было бы экранировать если бы слеш использовался в качестве ограничителей, а у вас стоят диезы.

Гуру, поправьте, если можно проще smile Первая выглядит "приятнее", но какая работает быстрее?

Автор: gta4kv 14.4.2008, 22:11
Sannis, пасибо))

Автор: source777 15.4.2008, 00:02
Код

"#\[youtube\]http:\/\/((ru|tw|jp|kr|au|br|ca|de|es|fr|ie|it|mx|nl|nz|pl|ul)\.)?youtube.com\/watch[?]v=([a-zA-Z0-9-_.=]+)\[/youtube\]#is"
Чтобы пометить часть регулярки как необязательную существует символ "?"
Я бы упростил до
Код

"#\[youtube\]http://(\w\w\.)?youtube.com/watch\?v=([\w\d_.=-]+)\[/youtube\]#is"

Автор: SelenIT 15.4.2008, 05:38
Насколько мне известно, \d входит в \w (равно как и _), поэтому \w\w для двух букв - это уж слишком упрощение smile. Кроме того, в некоторых локалях в \w могут попасть и русские буквы (хотя вряд ли их вставят в соотв. bb-код, но все же).

Цитата(Sannis @  14.4.2008,  21:53 Найти цитируемый пост)
Первая выглядит "приятнее", но какая работает быстрее?

Имхо, одинаково. Быстрее должно стать, если сделать скобки незахватывающими (?: ... ), а еще лучше однократными (?> ... ).

Автор: sTa1kEr 15.4.2008, 12:31
Цитата(source777 @  15.4.2008,  01:02 Найти цитируемый пост)
Я бы упростил до

Я так полагаю, что автор не от нечего делать перечислил все суб домены, что бы их просто так вот упрощать.

Цитата(source777 @  15.4.2008,  01:02 Найти цитируемый пост)
watch[?]v=

Забавно  smile Это новый способ экранирования? Работать, конечно, будет, но лучше все-таки экранировать традиционным способом при помощи обратного слеша.

Цитата(Sannis @  14.4.2008,  22:53 Найти цитируемый пост)
[a-zA-Z0-9-_.=]\[/youtube\]#is

А вот это уже грубая ошибка. Знак '-' в сете надо обязательно экранировать. И еще зачем тут знак '=' ?

Цитата(source777 @  15.4.2008,  01:02 Найти цитируемый пост)
([a-zA-Z0-9-_.=]+)\[/youtube\]#is

Нет смысла перечислять оба регистра букв, если стоит модификатор 'i'.  Единственный случай, когда это может использоваться - это для русских букв при криво настроенной локали. Но в этом случае это может привести к багам с экзотическими кодировками.

Цитата(SelenIT @  15.4.2008,  06:38 Найти цитируемый пост)
Быстрее должно стать, если сделать скобки незахватывающими (?: ... ), а еще лучше однократными (?> ... ). 

Со вторым согласен, а вот насчет того что незахватывающие скобки сколько-нибудь сильно ускорят регулярку - очень сомневаюсь. Имхо, есть смысл только для того что бы удобнее было работать с результатами.

Цитата(Sannis @  14.4.2008,  22:53 Найти цитируемый пост)
Первая выглядит "приятнее", но какая работает быстрее?

Хороший пример сложных регулярок, выглядящих "приятно", есть у Котерова. К примеру, http://dklab.ru/wsvn/lib/DbSimple/trunk/lib/DbSimple/Generic.php, метод _expandPlaceholdersFlow. 

Автор: source777 15.4.2008, 18:55
Цитата(sTa1kEr @  15.4.2008,  12:31 Найти цитируемый пост)
Нет смысла перечислять оба регистра букв, если стоит модификатор 'i'. 
В том примере, я просто добавил ? к исходному выражению, а в упрощенном варианте уже исправил эту избыточность...

Цитата(SelenIT @  15.4.2008,  05:38 Найти цитируемый пост)
поэтому \w\w для двух букв - это уж слишком упрощение
ОК, тогда упростим до [a-z]{2}  smile 

Автор: sTa1kEr 15.4.2008, 23:11
Цитата(source777 @  15.4.2008,  19:55 Найти цитируемый пост)
В том примере, я просто добавил ? к исходному выражению, а в упрощенном варианте уже исправил эту избыточность...

В общем-то я к автору топика обращался, просто ваш пост ближе для цитирования оказался  smile 

А вот ошибку с -(тире) вы благополучно переняли у gta4kv

Автор: source777 16.4.2008, 12:31
Цитата(sTa1kEr @  15.4.2008,  23:11 Найти цитируемый пост)
А вот ошибку с -(тире) вы благополучно переняли у gta4kv
Тут ты уже ошибаешься, обрати внимание, я поместил "-" последним символом в диапазоне, и это совершенно правильно, т.к. в таком случае оно не нуждается(rtfm) в экранировании...

Автор: sTa1kEr 16.4.2008, 19:47
source777, И что? У автора в первом посте тоже "в ообщем-то будет работать". Но стоит ему захотеть расширить вашу регулярку, к примеру, добавить ~(тильду) в конец набора символов, и вся регулярка будет работать не правильно. Почему сразу не сделать правильно, заэкранировав спецсимволы, что бы регулярка всегда работала правильно без ошибок?

Кстати, еще нужно .(точку) экранировать.

Автор: source777 16.4.2008, 22:03
Цитата(sTa1kEr @  16.4.2008,  19:47 Найти цитируемый пост)
Кстати, еще нужно .(точку) экранировать. 
Точку в диапазоне не надо экранировать, она там не имеет спец. смысла...


Цитата(sTa1kEr @  16.4.2008,  19:47 Найти цитируемый пост)
Но стоит ему захотеть расширить вашу регулярку, к примеру, добавить ~(тильду) в конец набора символов, и вся регулярка будет работать не правильно. Почему сразу не сделать правильно, заэкранировав спецсимволы, что бы регулярка всегда работала правильно без ошибок?
Так она и будет сразу работать правильно и без ошибок, а если по пьяни(на трезвую то голову сложно забыть, что - должно быть последним символом диапазона) не добавлять в неподходящие места новые символы, то всегда будет так работать, хотя это уже дело вкуса, а поскольку о вкусах не спорят, то думаю нет смысла продолжать эту дискуссию...

Автор: sTa1kEr 16.4.2008, 22:26
Цитата(source777 @  16.4.2008,  23:03 Найти цитируемый пост)
Точку в диапазоне не надо экранировать, она там не имеет спец. смысла...

Естественно. Я про другую точку говорил.
Цитата(source777 @  15.4.2008,  01:02 Найти цитируемый пост)
?youtube.com/


Цитата(source777 @  16.4.2008,  23:03 Найти цитируемый пост)
ак она и будет сразу работать правильно и без ошибок, а если по пьяни(на трезвую то голову сложно забыть, что - должно быть последним символом диапазона) не добавлять в неподходящие места новые символы, то всегда будет так работать, хотя это уже дело вкуса, а поскольку о вкусах не спорят, то думаю нет смысла продолжать эту дискуссию...

В значении элмента XML знак '>' тоже парсер проглатывает, т.ч можно не заменять XML сущностями - и так сойдет. Главное на пьяную голову не забыть: поставь ты символ '<' и парсер загнется.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)