Консультация № 170588
19.07.2009, 21:03
0.00 руб.
0 2 0
Необходимо модифицировать регулярное выражение приведенное в приложении для корректной обработки строки следующего вида:

Код:
  $data = "qwert\'asdf\\\'zxcv\'poiu"; 
# qwert'asdf\'zxcv'poiu > $1 = asdf\'zxcv


Приложение:
Код:
while ($data =~ /name:'([^']*?)'/g) {
print "$1\n";
};

Обсуждение

Неизвестный
19.07.2009, 22:21
общий
Zetasm:
Зачем в строке в двойных кавычках экранировать одинарные кавычки?
Код:
$data = "qwert'asdf\\'zxcv'poiu"; 

Код:
print "$1\n";
эквивалентно
Код:
say $1;
при условии, что есть
Код:
use 5.010;


Предлагаю три варианта решения. Первый - с использованием так называемого zero-length assertion, проверяющего, не стоит ли перед кавычкой слэш.
Код:
say $1 while $data =~ /(?<!\\)'(.*?)(?<!\\)'/g;


Второе - то же самое, только с явным проходом по строке.
Код:
say $1 while $data =~ /\G.*?(?<!\\)'(.*?)(?<!\\)'/g; 


Третье - постепенное продвижение по строке с откусыванием неинтересных символов, проскакиванием экранированных кавычек.
Код:
say $1 while $data =~ /\G(?>(?:(?>[^\\']+)|\\')*)'((?>(?:(?>[^\\']+)|\\')*))'/g;

Третье, кстати, расширяется на случай строк, содержащих экранированный слеш и другие символы - вместо \\' в конструкции выбора можно поставить \\.

Если есть вопросы по работе регулярных выражений - welcome :)
С моей стороны вопрос экспертам, раз уж представился случай,- какая из этих регулярок быстрее работает, особенно в случае отсутствия совпадений?
Неизвестный
20.07.2009, 00:35
общий
Большое спасибо!

Зачем в строке в двойных кавычках экранировать одинарные кавычки?

Это просто не очень удачный пример. В действительность будет нечто вроде:
Код:
use LWP::Simple;
...
$data = get($url);


Воспользовался кодом:
Код:
say $1 while $data =~ /(?<!\\)'(.*?)(?<!\\)'/g;

Упростив до:
Код:
say $1 while $data =~ /'(.*?)(?<!\\)'/g;


Форма ответа