正则表达式:如何匹配字符串末尾的键值对序列

9 投票
1 回答
16134 浏览
提问于 2025-04-16 13:48

我正在尝试匹配出出现在(长)字符串末尾的键值对。这些字符串看起来像这样(我把"\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])

这样会更方便查找你想要的键(和对应的值)。

更多信息:


撰写回答