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

Я пишу синтаксический анализатор, используя ply, который должен идентифицировать строковые литералы FORTRAN. Они заключаются в одинарные кавычки, а управляющий символ — в двойные одинарные кавычки. то есть

'I don''t understand what you mean'

является допустимой экранированной строкой FORTRAN.

Ply принимает ввод в виде регулярного выражения. Моя попытка пока не работает, и я не понимаю, почему.

t_STRING_LITERAL = r"'[^('')]*'"

Любые идеи?


person Brendan    schedule 26.01.2010    source источник


Ответы (4)


Строковый литерал:

  1. Открытая одинарная кавычка, за которой следует:
  2. Любое количество двойных одинарных кавычек и не одинарных кавычек, затем
  3. Близкая одинарная кавычка.

Таким образом, наше регулярное выражение:

r"'(''|[^'])*'"
person Anon.    schedule 26.01.2010
comment
Кажется, это не обрабатывает escape-последовательности. - person Cyoce; 07.04.2016

Вы хотите что-то вроде этого:

r"'([^']|'')*'"

Это говорит о том, что внутри одинарных кавычек вы можете иметь либо двойные кавычки, либо символ без кавычек.

Скобки определяют класс символов, в котором вы перечисляете символы, которые могут совпадать или не совпадать. Он не допускает ничего более сложного, поэтому попытка использовать круглые скобки и сопоставить многосимвольную последовательность ('') не работает. Вместо этого ваш класс символов [^('')] эквивалентен [^'()], то есть он соответствует всему, что не является одинарной кавычкой или левой или правой скобкой.

person John Kugelman    schedule 26.01.2010

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

>>> import pyparsing
>>> pyparsing.quotedString.reString
'(?:"(?:[^"\\n\\r\\\\]|(?:"")|(?:\\\\x[0-9a-fA-F]+)|(?:\\\\.))*")|(?:\'(?:[^\'\\n\\r\\\\]|(?:\'\')|(?:\\\\x[0-9a-fA-F]+)|(?:\\\\.))*\')'

Я не уверен в существенных различиях между строковыми литералами FORTRAN и Python, но это удобный справочник, по крайней мере.

person Mu Mind    schedule 07.03.2011
comment
Это, кажется, не обрабатывает f-строки. - person Dmitri Nesteruk; 14.02.2019

import re

ch ="'I don''t understand what you mean' and you' ?"

print re.search("'.*?'",ch).group()
print re.search("'.*?(?<!')'(?!')",ch).group()

результат

'I don'
'I don''t understand what you mean'
person eyquem    schedule 07.03.2011