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

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

'I don''t understand what you mean'

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

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

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

Есть идеи?

Ответы [ 4 ]

20 голосов
/ 27 января 2010

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

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

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

r"'(''|[^'])*'"
4 голосов
/ 27 января 2010

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

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

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

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

0 голосов
/ 07 марта 2011
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'
0 голосов
/ 07 марта 2011

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

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

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

...