LINUX.ORG.RU

помогите в составлении регулярки

 


0

1

возникла необходимость отфильтровать все строковые константы в C\C++\Java коде. условимся, что все строковые константы оформлены в двойные кавычки, могут переноситься на другие строки, могут быть пустыми и могут иметь произвольное число экранированных кавычек ( \" ), также условимся что код строится и не содержит синтаксических ошибок. как составить выражение? я вроде составил для всего, кроме \"

\"(.|\n)*?\"
Как добавить поддержку \" ?

★★★★★

Последнее исправление: jcd (всего исправлений: 1)

\"(.|\n)|(\\\")*?\"

не?

anonymous
()

поправка - мой вариант работает в sublime, но не работает в egrep (выделяется целая строка, не берётся в учет ?-lazyness), реализация для которого является целевой.

\"(.|\n)|(\\\")*?\"

соответственно тоже не рабоатет

jcd ★★★★★
() автор топика
Ответ на: комментарий от gv

По-моему вы все повалитесь на "\\".

my @s = (
    'asd "\\" qwe"',
    'asd "\\\\" qwe"',
    'asd "\\\\\\" qwe"',
    'asd "\\ " qwe"',
    '"asd "\\" qwe"',
);

for my $s (@s) {
    if ($s =~ /("([^\\"]|\\\\|\\\")*")/) {
        print("$s  ->  $1\n");
    } else {
        print("$s  ->  FAIL\n");
    }
}
asd "\" qwe"  ->  "\" qwe"
asd "\\" qwe"  ->  "\\"
asd "\\\" qwe"  ->  "\\\" qwe"
asd "\ " qwe"  ->  " qwe"
"asd "\" qwe"  ->  "asd "
arturpub ★★
()
Ответ на: комментарий от arturpub

Кстати я не уверен, что |-группы хаваются гарантированно последовательно, поэтому может непереноситься или работать через раз.

arturpub ★★
()
Ответ на: комментарий от arturpub

Прошлый вариант загонялся на " \ ". Ультрафикс:

    if ($s =~ /("([^\\"]|\\.)*")/) {

arturpub ★★
()

Самая простая строка C

"((?:\\[\\tn"]|[^"\\])*)"

Строка С++11 (кроме Raw string литералов)

(?<prefix>L|u8?|U)?"(?<inner>(?:\\(?:['"?\\0abfnrtv]|[0-7]{1,3}|x[\dA-F]+|u[\dA-F]{4}|U[\dA-F]{8})|[^"\\])*)"

Для C++11 Raw string наверное будет так

(?<prefix>L|u8?|U)?R"(?:(?<delimiter>[^ \\()\"]{0,16})\()(?<inner>.*)(?:\)\k<delimiter>)"

Выражения не оптимизированы по времени исполнения

Uter
()

В сущности, проблема в том, что в подавляющем большинстве систем находить конструкции произвольной вложенности при помощи регулярных выражений невозможно. В течение долгого времени это утверждение было абсолютной истиной, но недавно в Perl, .NET и PCRE/PHP появились конструкции, позволяющие реализовать подобные проверки (стр. 394, 515 и 563 соответственно). Впрочем, даже без этих специальных конструкций можно построить регулярное выражение, которое будет находить вложенные конструкции до определенного уровня вложенности, но не до произвольного уровня. Всего один уро вень вложенности требует чудовищного выражения:
 \([^()]*(\([^()]*\)[^()]*)*\) 
Одна мысль о том, чтобы взяться за следующие уровни вложенности, наводит на меня ужас. Иногда приходится прибегать к другим способам, не связанным с регулярными выражениями. Но следующий фрагмент на Perl по заданному уровню вложенности $depth генерирует регулярное выражение, совпадающее вплоть до заданного уровня. В нем используется оператор Perl «строка х число», который повторяет строку в указанном количестве экземпляров:
$regex = '\(' . '(?:[^()]|\(' х $depth . '[^()]*' . '\))*' х $depth . '\)';
Читатель может проанализировать его самостоятельно.

Регулярные выражения, Джеффри Фридл

Jaeger1999 ★★★
()
Ответ на: комментарий от arturpub

По-моему вы все повалитесь на «\\».

Даа, точно.

gv
()
Ответ на: комментарий от arturpub

По-моему вы все повалитесь на "\\".

А если так: "(\\.|[^"\\]|\n)*"?

Надеюсь с экранированием скобок и | сам разберешься.

Правда, здесь нет обработки задания символов с помощью 8- и 16-ричных кодов.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.