首页 > 解决方案 > Python Regex:从字符串中解析键/值对

问题描述

我正在尝试将如下字符串分解为键/值对列表:

line1 = "keyword1: value1 keyword2: value2 keyword1: value3 keyword3: value4"

我使用正则表达式编写了以下代码来实现该目标:

import re

line1 = "keyword1: value1 keyword2: value2 keyword1: value3 keyword3: value4"

keywords = [ re.escape(k) for k in ['keyword1', 'keyword2', 'keyword3'] ]

any_keyword = '|'.join(keywords)
regex = "(" + any_keyword + "):(.+?)(?:" + any_keyword + "|$)"

print(line1)
print(regex)

for m in re.finditer(regex, line1):
  print(m)

我得到的比赛是

<re.Match object; span=(0, 25), match='keyword1: value1 keyword2'>
<re.Match object; span=(34, 59), match='keyword1: value3 keyword3'>

而且,当然,它们在字符串的末尾包含关键字 2 和关键字 3,这样我就不会为这些关键字获得额外的匹配对象。

我怎样才能收到 4 个匹配项,一行中的每个关键字一个匹配项?

标签: pythonregex

解决方案


您可以使用前瞻而不是非捕获组作为正则表达式中的最后一个模式来提取匹配项,因为非捕获组模式仍然消耗字符:

import re
line1 = "keyword1: value1 keyword2: value2 keyword1: value3 keyword3: value4"
keywords = ['keyword1', 'keyword2', 'keyword3']
any_keyword = '|'.join(map(re.escape, keywords))
regex = "(" + any_keyword + "):(.+?)(?=(?:" + any_keyword + "):|$)"
print([m.group() for m in re.finditer(regex, line1)])
# => ['keyword1: value1 ', 'keyword2: value2 ', 'keyword1: value3 ', 'keyword3: value4']

查看Python 演示

如果您的键可以包含空格,请确保在定义any_keyword模式之前对键进行排序,方法是按长度按降序对它们进行排序,例如sorted(keywords,key=len,reverse=True).

将关键字作为整个单词进行匹配也是一个好主意:

regex = r"\b(" + any_keyword + r"):(.+?)(?=\b(?:" + any_keyword + "):|$)"

请参阅正则表达式演示。细节:

  • \b- 单词边界
  • (keyword1|keyword2|keyword3)- 第 1 组:关键字替代品
  • :- 一个:字符
  • (.+?)- 第 2 组:尽可能少的除换行符以外的任何一个或多个字符
  • (?=\b(?:keyword1|keyword2|keyword3):|$)- 一个积极的前瞻,确保在当前位置的右侧,有
    • \b(?:keyword1|keyword2|keyword3):- 列表中的任何关键字,后跟:
    • |- 或者
    • $- 字符串结束。

推荐阅读