2015-02-27 2 views
1

Я использую flex для разбора всего материала buncha, но я попал в roadbloack, когда попытался обнаружить два строковых литерала на одной строке.множественный строковый литерал в flex

мое регулярное выражение:

["].*["] 

Вот что я имею в виду:

"cats" < "dogs" 

признается в качестве одной длинной строки

cats" < "dogs 

Почему прогибается рассматривает только две самые внешние котировки , вместо создания двух отдельных наборов? Я уверен, что проблема заключается в моем регулярном выражении, поэтому я задаю следующие вопросы:

Как написать регулярное выражение, которое в этом случае распознает маркеры STRING, LESS, STRING, а не только STRING ?

+0

На самом деле вы должны включить свое регулярное выражение. В противном случае трудно понять, почему он не делает то, что вы ожидаете. – rici

ответ

4

Я полагаю, вы используете шаблон, как это:

["].*["]    { return STRING; } 

Или, возможно,

["].*?["]    { return STRING; } 

Первый не будет работать, потому что прогибается всегда занимает самый длинный матч, матч, используя последний «, очевидно, длиннее. Второй вариант будет правильным в библиотеке регулярных выражений, которая реализует нежелательное повторение, но flex не имеет: в flex, .*? является просто необязательным .* (т. Е. ? не является оператором.)

Что вы на самом деле хотите, так это сопоставление строк символов, отличных от котировок. Таким образом, вы можете просто сказать, что:

["][^"]*["]   { return STRING; } 

[^"] будет соответствовать символу новой строки, в отличие от .. Если вам не нужны многострочные строки, вам нужно будет использовать [^"\n].

Очевидно, что выше не позволяет " появляться в строках, которые рано или поздно будет раздражать. Два популярных решения этой проблемы (C-стиль), чтобы позволить \„уйти“ следующий символ: ("a \" in a string")

["]([^"]|\\.)*["]  { return STRING; } 

или (SQL-стиль) требовать, чтобы внутренний " быть удвоена: (" а "" в строке "`)

["]([^"]|["]["])*["] { return STRING; } 
+0

Я включил редактирование. Это должно помочь будущим читателям с тем же вопросом. Вы наносите гвоздь прямо на голову. Я не ожидал, что там будет такое простое элегантное решение. Спасибо. –

1

Если честно, я не уверен, почему flex делает то, что он есть. Но чтобы ответить на ваш вопрос о том, как писать регулярные выражения, чтобы обнаружить этот случай:

/^\"(?=.*[\"].*[\"].*[\"])(?=.*[\<]).+?\"$/ 

Это RegEx будет соответствовать на линии, которая соответствует этим критериям:

  • начинается и заканчивается в кавычки
  • Содержит 3 кавычки после первого (указывает, что линия содержит две строки)
  • Содержит ровно один угловой кронштейн

Потому что я не знаю, соответствуют ли вам именно те критерии, которые вам нужны, я сломаю это регулярное выражение и некоторые важные компоненты.

После проверки первой кавычки, это опережение подпрограмма разобран:

(?=.*[\"].*[\"].*[\"])

Проверяется вперед в RegEx тему, чтобы увидеть, если есть еще три кавычки. Он сопоставляет все, за которым следует кавычек, три раза. Вы можете изменить это, чтобы проверить более или менее кавычки, добавив или удалив часть .*[\"].

Далее, у нас есть еще опережения подпрограммы:

(?=.*[\<])

Это проверяет, что есть по крайней мере один угловой кронштейн между первой и последней кавычкой. Если вы хотите проверить другие операции, вы можете добавить их в квадратные скобки в [\<], например: [\<\>\=\+].

И, наконец, мы сопоставляем любой символ один или несколько раз с .+?, а затем с окончательной кавычкой: \".

Важно отметить, что подпрограммы lookahead фактически не перемещаются по строке, поскольку они выполняют свою проверку. Например, если мы используем регулярное выражение /a(?=a)a/, оно будет соответствовать только двум последовательным символам 'a', а не трем.

Вот почему первый взгляд, о котором я упоминал выше, пытается найти 3 кавычки после первого.

Возможно, не ответ, который вы искали, но я надеюсь, что это немного поможет.

+0

flex не реализует утверждения lookahead. (Кроме того, OP просто хочет сопоставить одну строку.) – rici

+0

А, моя ошибка. Подтвердил ваш ответ. – mroemore

+0

Я ценю, что вы объяснили это в таком подробном описании. Даже если вы не дали мне ответа, который я ищу, вы ознакомили меня с некоторыми новыми инструментами, которые связаны с моей проблемой. –

Смежные вопросы