Что такое регулярное выражение для CDATA - PullRequest
4 голосов
/ 06 января 2011

Привет, у меня есть пример CDATA здесь

<![CDATA[asd[f]]]>

и

<tag1><![CDATA[asd[f]]]></tag1><tag2><![CDATA[asd[f]]]></tag2>

Регламент CDATA, который у меня есть, не может распознать это

"<![CDATA["([^\]]|"]"[^\]]|"]]"[^>])*"]]>"

этоне работает тоже

"<![CDATA["[^\]]*[\]]{2,}([^\]>][^\]]*[\]]{2,})*">"

Кто-нибудь, пожалуйста, дайте мне регулярное выражение для <![CDATA[asd[f]]]>, мне нужно использовать его в Lex / Flex

: я ответил на этот вопрос, пожалуйста, проголосуйте намой ответ, спасибо.

Ответы [ 6 ]

7 голосов
/ 06 января 2011

Достаточно просто, должно быть так:

<!\[CDATA\[.*?\]\]>

Как минимум работает на regexpal.com

3 голосов
/ 06 января 2011

Проблема в том, что это довольно неудобно для сравнения с регулярными выражениями, используемыми в lex; если у вас есть система, которая поддерживает ERE, то вы сможете сделать либо:

<!\[CDATA\[(.*?)\]\]>

или

<!\[CDATA\[((?:[^]]|\](?!\]>))*)\]\]>

(В первом используются негладкие квантификаторы, во втором - отрицательные ограничения на просмотр. Хорошо, он также использует неотслеживающие парены, но вместо этого вы можете использовать их взятие; это не так важно.)

Вероятно, легче справиться с этим, используя стратегию, аналогичную способу обработки комментариев в стиле C в lex, имея одно правило, совпадающее с началом CDATA (на <![CDATA[) и помещающее лексер в отдельное состояние, которое он оставляет при просмотре ]]>, собирая все промежуточные символы. Это поучительно по этой теме (и, похоже, это область, в которой flex и lex отличаются), и оно охватывает все стратегии, которые вы можете использовать, чтобы сделать эту работу.

Обратите внимание, что причина всех этих проблем заключается в том, что очень трудно написать правило с простыми регулярными выражениями, которое выражает тот факт, что жадное регулярное выражение должно соответствовать ], только если за ним не следует ]>. Это гораздо проще сделать, если у вас есть только двухсимвольная (или односимвольная!) Последовательность конца интересного раздела, потому что вам не нужен такой сложный конечный автомат.

2 голосов
/ 07 января 2011

Это решение. Причина, по которой нам нужно использовать START STATE, заключается в том, что то, что когда-либо находится между <!CDATA[ и ]]>, не совпадает с другим REGEX.

%option noyywrap
%x CDATA

%%
"<![CDATA[" { BEGIN CDATA; printf("Entering CDATA\n"); }
<CDATA>([^\]]|\n)*|.    { printf("In CDATA: %s\n", yytext); }
<CDATA>"]]>" { 
    printf("End of CDATA\n");
    BEGIN INITIAL;
}

%%
main()
{
    yylex();
}
0 голосов
/ 20 марта 2012
<!\[CDATA\[\s*(?:.(?<!\]\]>)\s*)*\]\]>

Предыдущий ответ только что изменен

0 голосов
/ 06 января 2011

Одно примечание - поиск CDATA должен также исключать комментарии, CDATA может быть встроен.
/<!(?:\[CDATA\[(.*?)\]\]|--.*?--|\[[A-Z][A-Z\ ]*\[.*?\]\])>/sg
Это можно сделать, проверив, действительна ли группа 1 при каждом совпадении, возвращенном в глобальном поиске.

0 голосов
/ 06 января 2011

Полагаю, этот другой SO-ответ может быть полезен, даже если он захватывает содержимое HTML и является .NET.

На этот же вопрос есть другие ответы с различными вариантами захвата CDATA.

ответ ЧАДА:

<!\[CDATA\[(.*?)\]\]>

Соответствует:

<![CDATA[asd[f]]]>

получает:

asd[f]

По данным FlexRegEx в любом случае.

...