Вот пример типа текстового файла, который я пытаюсь найти (с именем usefile):

ДОК звукоподражания ДОК-бла-бла
бла ДОК бла
ДОК
бла-бла-бла
звукоподражание
бла-бла-бла
бла-бла ДОК
ДОК-бла-бла
ДОК-бла
звукоподражание

Я использую оператор finditer, чтобы найти все, что находится между DOCK и звукоподражанием, следующим образом:

re.finditer(r'((dock)(.+?)(onomatopoeia))', usefile, re.I|re.DOTALL)

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

Чтобы было понятно, что я хочу сверху:
1. ДОК-звукоподражание
2. ДОК-бла-бла-бла звукоподражания
3. ДОК бла звукоподражания

Есть ли способ найти звукоподражание и перейти к первому экземпляру Dock или лучший способ решить мою проблему?

Благодарность!

0
dandyjuan 13 Июл 2010 в 02:05

2 ответа

Лучший ответ

Утверждение отрицательного просмотра вперед сделает свое дело.

DOCK((?!DOCK).)+?onomatopoeia
4
Daniel Brückner 12 Июл 2010 в 22:12

Вот алгоритмический подход:

  • установить pushing == false.
  • Разбейте текст на слова (например, отрезки букв) и перебирайте их.
  • после нажатия DOCK и нажатия == false помещаем его в стек и устанавливаем pushing = true
  • если вы нажмете ono ... и нажмете == true, распечатайте все, что находится в стеке, плюс ono ..., затем очистите стек и установите pushing = false.
  • любое другое слово, если нажимается == true, нажмите его.
  • DOCK, при нажатии == true очистите стек, а затем вставьте новый DOCK.
0
Carl Smotricz 12 Июл 2010 в 22:17