#python #regex
#python #регулярное выражение
Вопрос:
у меня есть текстовый файл, который выглядит примерно так ,
<b-colophon>
data
</b-colophon>
<1|1|1|>
data,data,data
</1|1|1>
<1|1|2>
data,data,data
</1|1|2>
Итак, я хотел сделать тег ключом, а данные в теге — значением, и поэтому пришел с кодом —
dict1 = {}
lines = file.readlines()
for i in range(len(lines)):
try:
if lines[i].startswith('<') and lines[i 1] != 'n':
dict1[lines[i].strip()] = lines[i 1].strip()
except:
print("File read complete!")
print(dict1)
Но я требую, чтобы к ключу добавлялись только теги, начинающиеся с ‘<‘ и следующие, содержащие число, а строка, заключенная в этот тег, добавлялась к соответствующему значению. Но приведенный выше код добавляет все теги, начинающиеся с ‘<‘. Я хочу иметь возможность добавлять только теги, начинающиеся с ‘<‘, за которыми следует число, добавляемое в качестве ключа, даже не </> (закрывающие теги), а только открывающие теги. Пожалуйста, помогите.
Комментарии:
1. Почему вы отметили это
regex
, но вы не используете регулярные выражения?
Ответ №1:
Прежде всего:
<1|1|1|>
data,data,data
</1|1|1>
Должно быть:
<1|1|1|>
data,data,data
</1|1|1|>
Метод, который приходит на ум для этого, заключается в использовании регулярных выражений:
<(d [^>]*)>s*([sS]*?)s*</1>
<
Соответствует <(d [^>]*)
Соответствует одной или нескольким цифрам, за которыми следует 0 или более символов none > в группе захвата 1 (тег)>
Совпадения>s*
Соответствует 0 или более пробелам([sS]*?)
Сопоставляет 0 или более символов без жадности в группе захвата 2 (данные)s*
Соответствует 0 или более пробелам</
Соответствует </1
Соответствует группе захвата 1 (тегу)>
Совпадения>
Приведенное выше регулярное выражение удаляет начальные и конечные пробелы из данных (пункты 4 и 6 выше).
Смотрите Демонстрацию регулярных выражений
Код:
import re
text = """<b-colophon>
data
</b-colophon>
<1|1|1|>
data,data,data
</1|1|1|>
<1|1|2>
data,data,data
</1|1|2>
"""
rex = r'<(d [^>]*)>s*([sS]*?)s*</1>'
dict1 = {m[1]: m[2] for m in re.finditer(rex, text)}
print(dict1)
С принтами:
{'1|1|1|': 'data,data,data', '1|1|2': 'data,data,data'}
Естественно, вы бы изменили приведенный выше код так, чтобы это text
было file.read()
, то есть все содержимое файла в виде одной строки.
Если вы хотите <
, чтобы и >
были частью ключей словаря, внесите следующее изменение:
rex = r'<(d [^>]*)>s*([sS]*?)s*</1>'
d = {'<' m[1] '>': m[2] for m in re.finditer(rex, text)}
print(d)
С принтами:
{'<1|1|1|>': 'data,data,data', '<1|1|2>': 'data,data,data'}