регулярное выражение python отрицательный взгляд за утверждением, последующие захваченные начальные и конечные индексы группы неверны?

это у меня ломает голову...

Следующий код иллюстрирует проблему в python 2.7:

import re

test_string = "wqdwc ww w w\nwcw w wef wefwe fq\nWrite {\ndfwdfwdc\ndfdfwdf wef we\nwefwe wefwe ewf\nwefdww {{ wefwe, wefwe, wef, } \n}\nwqef wefwef qw\n}\nwef qw qfg3g q g\ng332r256\n32e5\n"

node_descr_re = re.compile('\n([A-Z]\w+\d*)\s\{.+?(?<! )\n(\})', re.DOTALL)

node_descr_match = node_descr_re.search( test_string )

node_block = node_descr_match.group()

print("---------------------------")
print("Matched string: \n{}".format( node_block ))
print("---------------------------")
print("Node block length: {}".format( len(node_block) ))
print("group(2) start index: {}".format( node_descr_match.start(2) ))
print("group(2) end index: {}".format( node_descr_match.end(2) ))
print("group(2) capture: {}".format( node_descr_match.group(2) ))

Я запускаю это и получаю:

---------------------------
Matched string: 

Write {
dfwdfwdc
dfdfwdf wef we
wefwe wefwe ewf
wefdww {{ wefwe, wefwe, wef, } 
}
wqef wefwef qw
}
---------------------------
Node block length: 99
group(2) start index: 129
group(2) end index: 130
group(2) capture: }

Регулярное выражение правильно соответствует описанию узла среди тарабарщины и правильно применяет отрицательный вид за утверждением, игнорируя появление \n и закрывающей фигурной скобки, перед которой есть пробел, но используя последующую \n и закрывающую фигурную скобку. перед которыми нет пробела.

Вывод операторов печати должен проиллюстрировать, что меня беспокоит. Они показывают, что group(2) успешно захватила закрывающую фигурную скобку описания узла. Но хотя полная длина совпадения описания узла (блок узла) составляет 98 символов, начальный индекс захваченного последнего символа (закрывающая фигурная скобка, захваченная группой (2)) равна 128 ????

Кто-нибудь может пролить свет?

РЕДАКТИРОВАТЬ - относится ли индекс к позиции совпадения в исходной строке test_string? Кажется, это ответ. Извините за вопрос - я иногда путаюсь в начальных и конечных индексах групп, относящихся к позициям в исходной строке, а не в самом совпадении.


person Malcolm Wright    schedule 25.10.2016    source источник


Ответы (1)


>>> test_string[129:]
'}\nwef qw qfg3g q g\ng332r256\n32e5\n'

Это показывает, что закрывающая фигурная скобка действительно появляется по индексу 129 = node_descr_match.start(2). Обратите внимание, что сам node_block тоже не начинается с индекса 0. Начинается в 31 год:

>>> test_string.index("\nWrite")
31

node_block — это полное соответствие, поэтому охватывает test_string[31 : 31+99] = test_string[31 : 130]. Закрывающая фигурная скобка является его последним символом, поэтому и в этом представлении его индекс должен быть 130-1 = 129.

Здесь я не вижу противоречия.

person Tim Peters    schedule 25.10.2016
comment
Спасибо Тим - как это часто бывает, до меня начало доходить, что индексы относятся к исходной строке, с которой сравнивается, а не к самому совпадению! Мне часто приходится дважды подумать, чтобы запомнить это - на этот раз потребовалось немного больше! - person Malcolm Wright; 25.10.2016