Соответствует произвольной Python строке с Python регулярным выражением? - PullRequest
1 голос
/ 28 февраля 2020

Я работаю с Python корпусом исходного кода. Я хотел бы, чтобы строки были заменены на STRING. Python строки раздражают, потому что они позволяют так много разделителей. Вот то, что я пробовал, и проблемы, с которыми я столкнулся.

  • r'"(\\"|[^"])*"' и r"'(\\'|[^'])*'"

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

  • r'(\'|"|\'\'\'|""")(?:\\\1|(?!\1))*\1'

    Это была моя попытка поймать все, но упреждение не сработало. Я в основном хотел r'(\'|"|\'\'\'|""")(?:\\\1|[^\1])*\1', если бы это было возможно.

  • Многострочные строки портят вещи. Вы не можете использовать [^"""], потому что """ не является одним символом.

  • Строки, которые содержат другие разделители, такие как "'".
  • Строки, которые экранируют разделитель как '\''.

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

  • '/$\'"`'
  • '\\'
  • '^__[\'\\"]([^\'\\"]*)[\'\\"]'
  • "Couldn't do that"

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

def hello_world():
    print("'blah' \"blah\"")

Чтобы стать:

def hello_world():
    print( STRING )

Для простоты, скажем, весь файл Python находится внутри строки. Прямо сейчас я читаю файл построчно, но при необходимости могу рассматривать его как одну строку. Это действительно не имеет значения, как файл читается. Если ваше решение требует определенного c метода, я буду его использовать. Я не уверен, что эту проблему можно полностью решить с помощью регулярных выражений. Если у вас есть решение, включающее другой код, это также будет высоко оценено.

1 Ответ

1 голос
/ 29 февраля 2020

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

[rR]?(?:'([^\\']*(?:\\.[^\\']*)*)'|"([^\\"]*(?:\\.[^\\"]*)*)")

Демо

Хотя это может охватить большинство строк, я уверен, Есть еще некоторые исключения.

Это основано на Дж. Фридла, разворачивающем технику l oop:

Развертывание L oop (с использованием двойных кавычек)

"                              # the start delimiter
 ([^\\"]*                      # anything but the end of the string or the escape char
         (?:\\.                #     the escape char preceding an escaped char (any char)
               [^\\"]*         #     anything but the end of the string or the escape char
                      )*)      #     repeat
                             " # the end delimiter
...