Экранирование кавычек при выделении строк из ввода - PullRequest
0 голосов
/ 06 марта 2012

Я пытаюсь разобрать файл, в котором файлы цитат используются для инкапсуляции строк.Например, файл может содержать такую ​​строку:

    "\"Hello there, my friends,\" the tour guide says." me @ swap notify

Но он также может содержать строки, подобные этой:

    "I'm a dingus who wants to put a backslash at the end of my statements. \\" me @ swap notify

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

Можно ли использовать какую-либо функцию для извлечения этого оператора в кавычках?\ n для перехода на новую строку и \ r для возврата каретки также иногда появляются, поэтому я хотел бы получить эти два, но только после того, как у меня будет выделена полная строка.

Ответы [ 2 ]

2 голосов
/ 06 марта 2012
  1. Разобрать строковую часть.Вы можете использовать регулярное выражение или строковое разбиение
  2. ast.literal_eval строку и присвоить ее переменной.

Тест:

>>> import re
>>> import ast
>>> with open('test.txt.') as f:
...  for line in f:
...   m = re.match('(.*) \w+ @ \w+ \w+', line)
...   print ast.literal_eval(m.group(1))
...
"Hello there, my friends," the tour guide says.
I'm a dingus who wants to put a backslash at the end of my statements. \

Регулярное выражение говорит: "Сопоставьте что-нибудь и сохраните его как группа 1 , до пробела, слова, пробела, знака @, пробелаи слово ".Затем вы получите группу с синтаксисом .group(1).Круглые скобки определяют группу, см. документацию по регулярным выражениям .

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

import re
import ast

def match_line(line):
    while line:
        print "Trying to match:", line
        try:
            return ast.literal_eval(line)
        except SyntaxError, e:
            line = line[:e.offset - 1]
        except ValueError: # No way it would ever match
            break
    return None

with open('test.txt.') as f:
    for line in f:
        match = match_line(line.strip())
        print "Matched:", match
        print
1 голос
/ 06 марта 2012

Вы можете использовать регулярные выражения.Обычно это не рекомендуется для анализа, потому что, если у вас нет достаточно простых входных данных или входных данных, которые следуют строгим правилам, легко допустить ошибки.Вероятно, существует какой-то модуль синтаксического анализа, который справляется с этим лучше (например, модуль csv отлично подходит для кавычек в полях и экранирования, если у вас есть CSV).

txt1 = r'"\"Hello there, my friends,\" the tour guide says." me @ swap notify.'
txt2 = '"I' + "'" + r'm a dingus who wants to put a backslash at the end of my statements. \\" me @ swap notify'

import re
print re.findall(r'"(?:[^"\\]|\\.)+"',txt1)[0]
# "\"Hello there, my friends,\" the tour guide says."
print re.findall(r'"(?:[^"\\]|\\.)+"',txt2)[0]
# "I'm a dingus who wants to put a backslash at the end of my statements. \\"

Примечание. Я использовалСинтаксис r'xxxxx', чтобы избежать дальнейшей экранизации для python (они уже экранированы для регулярных выражений).

Регулярное выражение "([^"\\]|\\.)+" говорит: «сопоставить все, что не является» или обратный слеш, ИЛИ сопоставлениеобратный слеш и все, что следует за ним. "

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