【问题标题】:Python Regex Key Value MatchingPython 正则表达式键值匹配
【发布时间】:2019-08-17 00:30:00
【问题描述】:

我有一个要解析的文件,其中包含键值对。键以“-”开头,后跟字母字符,然后是值,如下图所示。

当我使用以下正则表达式模式解析文件时,我很容易获得键和值,但是当值包含多个单词或引用数据(也与键值匹配)时,我的模式匹配失败。我已经尝试了正则表达式模式匹配的多次迭代,但未能获得所需的输出。我设法找到一个正则表达式模式来匹配引用的文本'"(.*?)"' 但无法同时使用这两种模式。非常感谢任何有助于获得以下所需输出的帮助。

我的代码(仅第一行所需的结果)

mystring = '''-desc none -type used -cost med -color blue
-desc none -msg This is a a message -name test
-desc "(-type old -cost high)" -color green'''

mydict = {}
item_num = 0
for line in mystring.splitlines():
    quoted = re.findall('"(.*?)"', line)
    key_value = re.findall('(-\w+\s+)(\S+)', line)
    print(key_value)

### Output ###
[('-desc ', 'none'), ('-type ', 'used'), ('-cost ', 'med'), ('-color ', 'blue')]
[('-desc ', 'none'), ('-msg ', 'This'), ('-name ', 'test')]
[('-desc ', '"(-type'), ('-cost ', 'high)"'), ('-color ', 'green')]

### Desired Output ###
[('-desc ', 'none'), ('-type ', 'used'), ('-cost ', 'med'), ('-color ', 'blue')]
[('-desc ', 'none'), ('-msg ', 'This is a message'), ('-name ', 'test')]
[('-desc ', "(-type old -cost high)"), ('-color ', 'green')]

【问题讨论】:

  • 检查ideone.com/YSw8Cr - 是否按预期工作?
  • 这是惊人的正则表达式魔法!是的,完全按预期工作。您能否简要解释一下这里使用的正则表达式模式?谢谢。

标签: regex python-3.x regex-greedy


【解决方案1】:

这是您可以使用的最佳正则表达式:
改变您的投票永远不会太晚。

正则表达式原始:

(?<!\S)-(\w+)\s+("[^"]*"|[^\s"-]+(?:\s+[^\s"-]+)*)(?!\S)

python 原始

r"(?<!\S)-(\w+)\s+(\"[^\"]*\"|[^\s\"-]+(?:\s+[^\s\"-]+)*)(?!\S)"

https://regex101.com/r/7bYN1A/1

密钥 = 第 1 组
值 = 第 2 组

 (?<! \S )
 -
 ( \w+ )                       # (1)
 \s+ 
 (                             # (2 start)
      " [^"]* "
   |  [^\s"-]+ 
      (?: \s+ [^\s"-]+ )*
 )                             # (2 end)
 (?! \S )

基准测试

Regex1:   (?<!\S)-(\w+)\s+("[^"]*"|[^\s"-]+(?:\s+[^\s"-]+)*)(?!\S)
Options:  < none >
Completed iterations:   50  /  50     ( x 1000 )
Matches found per iteration:   10
Elapsed Time:    1.66 s,   1660.05 ms,   1660048 µs
Matches per sec:   301,196

【讨论】:

  • 这不包括带有“\”和“\&”等特殊字符的值。例如:“-desc n&one -type used -cost med -color bl\ue”。这是它不匹配“n&one”和“bl\ue”。是否可以更新以在值中包含特殊字符?
  • @MBasith - 引号是否被视为单个值:-this "quoted"?或者它可以与其他字符/引号混合在一个值中:-that here"quoted"there"quoted"?或者一个值可以包含 1,2,3,4,.... 不同的引号?如果你不知道也没关系。
  • 引号被视为单个值。值将只包含一对引号。
  • 这很好用!请问你这个是怎么生成的?是仅仅通过使用 RegEx 的一般知识和经验,还是您有一些工具可以提供帮助?
  • 我使用RegexFormat 来开发、测试、维护、基准正则表达式。我已经开发了数百个正则表达式文件。使用这个工具,大大减少了学习时间。
【解决方案2】:

你可以使用

(-\w+)\s+("[^"]*"|.*?)(?=$|\s*-\w+\s)

请参阅regex demo

详情

  • (-\w+) - 第 1 组:- 和 1+ 个单词字符
  • \s+ - 1+ 个空格
  • ("[^"]*"|.*?) - 第 2 组:",除 " 之外的 0+ 个字符,然后是 " 或除换行符之外的任何 0+ 个字符,尽可能少,直到第一个 ...
  • (?=$|\s*-\w+\s) - 字符串结尾或 0+ 个空格、-、1+ 个单词字符和一个空格。

正则图:

Python demo

import re
mystring = '''-desc none -type used -cost med -color blue
-desc none -msg This is a a message -name test
-desc "(-type old -cost high)" -color green'''

mydict = {}
for line in mystring.splitlines():
    key_value = re.findall(r'(-\w+)\s+("[^"]*"|.*?)(?=$|\s*-\w+\s)', line)
    print(key_value)

输出:

[('-desc', 'none'), ('-type', 'used'), ('-cost', 'med'), ('-color', 'blue')]
[('-desc', 'none'), ('-msg', 'This is a a message'), ('-name', 'test')]
[('-desc', '"(-type old -cost high)"'), ('-color', 'green')]

【讨论】:

  • 这太棒了。感谢您的详细解释和视觉效果!
猜你喜欢
  • 1970-01-01
  • 2023-01-23
  • 2016-07-01
  • 2013-09-22
  • 2022-12-11
  • 2015-09-14
  • 2021-12-31
  • 2018-12-30
  • 1970-01-01
相关资源
最近更新 更多