Вложенность в регулярных выражениях

Мастера регулярных выражений могут делать настоящую магию. Вместо того, чтобы писать сложные лексические анализаторы, они могут одной строчкой сделать всю работу. Это как игра го - изучить основы очень просто, но чтобы стать настоящим профессионалом нужны годы опыта.

Допустим, есть строка

CODE:
  1. begin someFunction("test"); end;

Нужно выделить из неё

CODE:
  1. ("test")

Элементарно

PHP:
  1. $s = 'begin someFunction("test"); end;';
  2. preg_match('#\(.*?\)#', $s, $m);
  3. print_r($m);

выведет

PHP:
  1. (
  2.     [0] => ("test")
  3. )

Но в боевых условиях пользователи обязательно рано или поздно добавят параметр со скобками

CODE:
  1. begin someFunction("test",(5+3)*2); end;

Наш код

PHP:
  1. $s = 'begin someFunction("test",(5+3)*2); end;';
  2. preg_match('#\(.*?\)#', $s, $m);
  3. print_r($m);

выведет

CODE:
  1. Array
  2. (
  3.     [0] => ("test",(5+3)
  4. )

А вот вам

PHP:
  1. $s = 'begin someFunction("test",(5+3)*2); end;';
  2. preg_match('#\((([^\(\)]+)|(?R))*\)#', $s, $m);
  3. print_r($m);

Это выведет

PHP:
  1. (
  2.     [0] => ("test",(5+3)*2)
  3.     [1] => *2
  4.     [2] => *2
  5. )

А теперь немного оптимизируем

PHP:
  1. preg_match('#\( (?: (?>[^\(\)]+) | (?R) )* \)#x', $s, $m);

Модификатор "x" даёт ставить лишние пробелы для улучшения читабельности.
?> - ускоряет производительность, не проверяя одни и те же символы, если они уже где-то подошли
?: - делает так, чтобы не выводилось это подвыражение (заметьте пропажу [1], [2])

PHP:
  1. (
  2.     [0] => ("test",(5+3)*2)
  3. )

Детальнее можно читать в мануале - http://php.net/manual/en/regexp.reference.php


Понравилось?

  1. Подпишись через RSS
  2. Расскажи о http://php.southpark.com.ua друзьям.
    Все способы хороши: ICQ, E-mail, свой блог, комментарий в чужом блоге или сообщение на форуме
  3. Добавь статью на news2.ru, Хабрахабр или в закладки

Огромное спасибо!

Похожие статьи

И не стесняйтесь комментировать - у меня стоит плагин, который убирает rel="nofollow" у людей, которые написали больше 5 комментариев.

RSS feed | Trackback URI

5 комментариев »

2008-06-06 10:33:32

На то они и мастера.

 
2008-07-04 16:23:25

begin someFunction("test"); end; А разве в пхп есть операторы бегин\енд??? Я что-то такого еще не слышал

2008-07-08 18:03:18

Нет, но ничего ни мешает существовать такой демо-строке :)

 
 
Comment by Виётк
2008-07-22 19:58:10

Обана, я раньше не знал этого. Надо будет изучить эту штуковину.

 
Comment by Voron
2008-08-23 11:42:56

Мастер ,да вы просто мастер:-)))

 
Имя (required)
E-mail (required - never shown publicly)
URL
Текст комментария
You may use <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> in your comment.