正则表达式:如何匹配字符串末尾的键值对序列
我正在尝试匹配出出现在(长)字符串末尾的键值对。这些字符串看起来像这样(我把"\n"替换掉了)
my_str = "lots of blah
key1: val1-words
key2: val2-words
key3: val3-words"
所以我希望能匹配到“key1: val1-words”、“key2: val2-words”和“key3: val3-words”。
- 可能的键名是已知的。
- 并不是每个字符串中都会出现所有可能的键。
- 每个字符串中至少会出现两个键(如果这样更容易匹配的话)。
- val-words可以是多个单词。
- 键值对只能在字符串的末尾匹配。
- 我正在使用Python的re模块。
我在想
re.compile('(?:tag1|tag2|tag3):')
加上一些前瞻性断言的东西可能是个解决方案。不过我一直搞不对。我该怎么做呢?
谢谢。
/David
真实的示例字符串:
my_str = u'ucourt métrage pour kino session volume 18\nThème: O sombres héros\nContraintes: sous titrés\nAuthor: nicoalabdou\nTags: wakatanka productions court métrage kino session humour cantat bertrand noir désir sombres héros mer medine marie trintignant femme droit des femmes nicoalabdou pute soumise\nPosted: 06 June 2009\nRating: 1.3\nVotes: 3'
编辑:
根据Mikel的解决方案,我现在使用以下内容:
my_tags = ['\S+'] # gets all tags
my_tags = ['Tags','Author','Posted'] # selected tags
regex = re.compile(r'''
\n # all key-value pairs are on separate lines
( # start group to return
(?:{0}): # placeholder for tags to detect '\S+' == all
\s # the space between ':' and value
.* # the value
) # end group to return
'''.format('|'.join(my_tags)), re.VERBOSE)
regex.sub('',my_str) # 返回不包含匹配的键值行的my_str
regex.findall(my_str) # 返回匹配的键值行
1 个回答
12
负零宽度前瞻是 (?!pattern)
。
这个内容在 re模块的文档页面 中提到过。
(?!...)
如果 ... 后面不匹配,就会匹配。这是一个负前瞻断言。举个例子,'Isaac (?!Asimov)' 只会在后面不是 'Asimov' 的时候匹配 'Isaac '。
所以你可以用它来匹配某个关键字后面的任意单词,但不包括某个关键字,比如用 (?!\S+:)\S+
。
完整的代码看起来是这样的:
regex = re.compile(r'''
[\S]+: # a key (any word followed by a colon)
(?:
\s # then a space in between
(?!\S+:)\S+ # then a value (any word not followed by a colon)
)+ # match multiple values if present
''', re.VERBOSE)
matches = regex.findall(my_str)
这样会得到
['key1: val1-words ', 'key2: val2-words ', 'key3: val3-words']
如果你用以下方式打印键/值:
for match in matches:
print match
它会打印:
key1: val1-words
key2: val2-words
key3: val3-words
或者用你更新的例子,它会打印:
Thème: O sombres héros
Contraintes: sous titrés
Author: nicoalabdou
Tags: wakatanka productions court métrage kino session humour cantat bertrand noir désir sombres héros mer medine marie trintignant femme droit des femmes nicoalabdou pute soumise
Posted: 06 June 2009
Rating: 1.3
Votes: 3
你可以用类似这样的方式把每个键/值对变成一个字典:
pairs = dict([match.split(':', 1) for match in matches])
这样会更方便查找你想要的键(和对应的值)。
更多信息: