Получать все между двумя персонажами через новые строки - PullRequest
2 голосов
/ 23 апреля 2020

Это образец текста, с которым я работаю.

6) Служба такси Джейка - новый участник индустрии такси. Он добился успеха, заняв уникальную позицию в отрасли. Как Служба такси Джейка, скорее всего, достигла этой позиции?

A) предоставляя тарифы на такси на большие расстояния по более высокой ставке, чем у конкурентов; обслуживание большей площади, чем у конкурентов

B) предоставление тарифов на междугородние такси по более низким тарифам, чем у конкурентов; обслуживание меньшей площади, чем у конкурентов

C), предоставление тарифов на междугородние такси по более высокой ставке, чем у конкурентов; обслуживание в той же зоне, что и конкуренты

D) предоставление тарифов на междугородние такси по более низкой ставке, чем у конкурентов; обслуживая ту же область, что и конкуренты

Ответ: D

Я пытаюсь сопоставить весь вопрос, включая варианты ответа. Все от номера вопроса до слова Ответ

Это мое текущее регулярное выражение

((rf'(?<={searchCounter}\) ).*?(?=Answer).*'), re.DOTALL)

SearchCounter - это просто переменная, которая будет соответствовать текущему вопросу, в данном случае 6 Я думаю, что проблема связана с поиском по новым строкам.

РЕДАКТИРОВАТЬ: Полный исходный код

searchCounter = 1

bookDict = {}

with open ('StratMasterKey.txt', 'rt') as myfile:

    for line in myfile:
        question_pattern = re.compile((rf'(?<={searchCounter}\) ).*?(?=Answer).*'), re.DOTALL) 

        result = question_pattern.search(line)
        if result != None: 
            bookDict[searchCounter] = result[0] 
            searchCounter +=1

Ответы [ 2 ]

1 голос
/ 24 апреля 2020

Причиной сбоя вашего регулярного выражения является то, что вы читаете файл построчно с помощью for line in myfile:, в то время как ваш шаблон ищет совпадения в одной многострочной строке .

Замените for line in myfile: на contents = myfile.read() и затем используйте result = question_pattern.search(contents) для получения первого совпадения или result = question_pattern.findall(contents) для получения нескольких совпадений.

Примечание к регулярному выражению: я не являюсь исправление всего шаблона, поскольку, как вы упомянули, это выходит за рамки этого вопроса, но поскольку ввод строки теперь является многострочной строкой, вам необходимо удалить re.DOTALL и использовать [\s\S] для сопоставления с любым символом в шаблоне и . для соответствия любому символу, кроме символа разрыва строки. Кроме того, обходной контур избыточен, вы можете смело заменять (?=Answer) на Answer. Кроме того, чтобы проверить, есть ли совпадение, вы можете просто использовать if result:, а затем получить все значение совпадения, набрав result.group().

Фрагмент полного кода:

with open ('StratMasterKey.txt', 'rt') as myfile:
    contents = myfile.read()
    question_pattern = re.compile((rf'(?<={searchCounter}\) )[\s\S]*?Answer.*')) 
    result = question_pattern.search(contents)
    if result: 
        print( result.group() )
0 голосов
/ 23 апреля 2020

Вы правы, что проблема связана с новыми строками. . соответствует всем символам , кроме новых строк. Вы можете сопоставить новую строку с [\r\n].

. Кроме того, ? после .* является избыточным, поскольку * означает «0 или более вхождений».

...