С регулярное выражение
import re
ss = '''
>Entry1.1
#size=1688
704 1 1 1 4
979 2 2 2 0
1220 1 1 1 4
1309 1 1 1 4
1316 1 1 1 4
1372 1 1 1 4
1374 1 1 1 4
1576 1 1 1 4
>Entry2.1
#size=6251
6110 3 1.5 0 2
6129 2 2 2 2
6136 1 1 1 4
6142 3 3 3 2
6143 4 4 4 1
6150 1 1 1 4
6152 1 1 1 4
>Entry3.2
#size=1777
AND SO ON-----------
'''
patbase = '(>Entry *%s(?![^\n]+?\d).+?)(?=>|(?:\s*\Z))'
while True:
x = raw_input('What entry do you want ? : ')
found = re.findall(patbase % x, ss, re.DOTALL)
if found:
print 'found ==',found
for each_entry in found:
print '\n%s\n' % each_entry
else:
print '\n ** There is no such an entry **\n'
Объяснение '(>Entry *%s(?![^\n]+?\d).+?)(?=>|(?:\s*\Z))'
:
1)
%s
получает ссылку на запись: 1.1, 2, 2.1 и т.д.
2)
Часть (?![^\n]+?\d)
должна сделать проверку.
(?![^\n]+?\d)
негативный взгляд вперед утверждение, что говорит, что после %s
не должно быть [^\n]+?\d
, что есть какие-либо символы [^\n]+?
перед цифрой \d
я пишу [^\n]
означает «любой символ, кроме символа новой строки \n
».
Я обязан написать это вместо простого .+?
, потому что я поставил флаг re.DOTALL
, а участок рисунка .+?
будет действовать до конца записи.
Однако, я только хочу, чтобы убедиться, что после введенного ссылки (представленного% s в шаблоне), не будет дополнительных цифр до конца строки, введенные ошибки
Все это происходит потому, что если есть Entry2.1, но нет Entry2, и пользователь вводит только 2, потому что он хочет Entry2, и никакое другое, регулярное выражение не обнаружит присутствие Entry2.1 и не даст его, хотя пользователю действительно понравится Entry2 на самом деле.
3)
В конце '(>Entry *%s(?![^\n]+?\d).+?)
, часть .+?
поймает полный блок Входа, потому что точка любого символа, содержал строку \n
Это для этой цели я поставил флаг re.DOTALL
, чтобы сделать следующий участок шаблона .+?
, способный передавать символы новой строки до конца записи.
4)
Я хочу согласующий, чтобы остановить в конце Введения желаемого, а не внутри следующей, так что группа определяется скобками в (>Entry *%s(?![^\n]+?\d).+?)
поймает именно то, что мы хотим
Следовательно, В конце я положил положительное утверждение (?=>|(?:\s*\Z))
, в котором говорится, что символ, перед которым бегущий неровный .+?
должен остановиться, должен совпадать, либо >
(начало следующей записи), либо конец строки \Z
.
Как нельзя возможно, что конец последней записи не будет точно концом всей строки, я ставлю \s*
, что означает «возможные пробелы до самого конца».
Так \s*\Z
означает «может быть пробелами, прежде чем врезаться в конец строки» Пробелов являются не blank
, \f
, \n
, \r
, \t
, \v
Благодарю вас. Я не видел, что вы видели мой ответ. Если вам нужны улучшения, спросите. Например, было бы интересно, чтобы пользователь мог ввести ** 1 1 ** вместо ** 1.1 ** – eyquem