Выражение Regex, которое включает в себя все, вплоть до символа, но игнорирует экранированные версии этого символа - PullRequest
0 голосов
/ 19 декабря 2018

У меня есть строка, которая включает несколько подстрок в кавычках.Мне нужно разделить эту строку на подстроки, где каждая подстрока является либо строкой в ​​кавычках, либо текстом между строками в кавычках, но она также должна игнорировать экранированные кавычки.

Примеры:

'"hello" "there"'
['"hello"', '"there"']

'MACRO "hello there"'
['MACRO', '"hello there"']

'"hello there" MACRO "again, \"Steve\""'
['"hello there"', 'MACRO', '"again, \"Steve\""']

'KERN \"  "Hello    there, \"buddy\""'
['KERN \"', '"Hello    there, \"buddy\""']

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

Я пытался использовать Shlex, но Shlex терпит неудачу с этой строкой:

c = r'KERN  "Hello    there, \"buddy\""'
print shlex.split(c, posix=False)
['KERN', '\\"', '"Hello    there, \\"', 'buddy\\""']

"Hello there" и "buddy" должныбыть частью одной и той же строки.

Самое близкое, что у меня есть, это:

>>> m = re.search(r'([^"]*)("?:[^"\\]|\\.*")', c)
>>> print m.groups()
('KERN ', '\\"  "Hello    there, \\"buddy\\""')

Проблема в первой группе.Мне нужно выражение, которое говорит: «хватайте все до первой кавычки, но не включая первую кавычку, но включайте экранированные кавычки».Я не знаю, как это сделать.

1 Ответ

0 голосов
/ 19 декабря 2018

Вы можете использовать это регулярное выражение с чередованием в findall, которое заботится о экранированных символах:

"[^"\\]*(?:\\.[^"\\]*)*"|\S+

Демонстрация RegEx

Код:

>>> arr = [ r'"hello" "there"', r'MACRO "hello there"', r'"hello there" MACRO "again, \"Steve\""' ]
>>> reg = re.compile(r'"[^"\\]*(?:\\.[^"\\]*)*"|\S+')
>>> for s in arr:
...     print (reg.findall(s))
...
['"hello"', '"there"']
['MACRO', '"hello there"']
['"hello there"', 'MACRO', '"again, \\"Steve\\""']

Подробности RegEx:

  • ": открытие матча "
  • [^"\\]*:Совпадение 0 или более любого символа, который не является " и \
  • (?:: начать группу без захвата
    • \\.: сопоставить \ с последующим следующим побегомсимвол
    • [^"\\]*: соответствует 0 или более символам, отличным от " и \
  • )*: конец группы без захвата, совпадение0 или более из этой группы
  • ": совпадение закрытия "
  • |: ИЛИ
  • \S+: совпадение 1+ непробельных символов
...