【问题标题】:Extract Keys and Values from text using regular expressions使用正则表达式从文本中提取键和值
【发布时间】:2020-07-10 16:29:41
【问题描述】:

我有大量的字符串需要解析。这些字符串包含放在键值对中的信息。

输入文本示例:

Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illoinvente veritatis et quasi architecto beatae vitae dicta sunt explicabo。 Nemo enim: ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt。 Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem。 Ut enim: ad minima veniam, *31.12.2012, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil Molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur

关键信息:

  • 键从字符串的开头或\. 之后开始
  • 密钥总是以: 结尾
  • 键后紧跟一个值
  • 此值一直持续到下一个键或字符串中的最后一个符号
  • 有多个键值对,我不知道

预期输出

{
    "Nemo enim": "ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem",
    
    "Ut enim": "ad minima veniam, *31.12.2012, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur. Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur"
}

我目前的正则表达式是([üöä\w\s]*)\: (.*?)\.。可以说它没有提供预期的输出。

【问题讨论】:

  • key 总是两个字吗?
  • 不,遗憾的是,键可以是 1 到 n 个单词之间的任何内容
  • : 是否出现在文本中除键之外的任何位置?
  • 键可以包含前导空格字符吗?
  • until the last symbol in the stringsymbol的定义是什么?

标签: python regex parsing


【解决方案1】:

这个正则表达式 ([^:.]+):\s*([^:]+)(?=\.\s+|$) 可以完成这项工作。

Demo & explanation

【讨论】:

  • 正则表达式很好,谢谢!它的问题是,它直到下一个值才会出现 > 这个值一直持续到下一个键或字符串中的最后一个符号在这种情况下,键 "Nemo enim" 的值也应该包含 . Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem
  • 这个正则表达式禁止使用冒号,除非它作为键终止符。包括一个时间,例如'10:15',会产生问题。 ref
【解决方案2】:

您可以匹配以下正则表达式,它保存键和值以捕获组 1 和 2。

r'(?<![^.]) *([^.]+?:) *((?:(?!\. ).)+)'

Start your engine! | Python code

Python 的正则表达式引擎执行以下操作。

(?<![^.])    : negative lookbehind asserts current location is not
               preceded by a character other than '.'
\ *          : match 0+ spaces
(            : begin capture group 1
  [^.]+?     : match 1+ characters other than '.', lazily
  :          : match ':'
)            : end capture group 1
\ *          : match 0+ spaces
(            : begin capture group 2
  (?:        : begin non-capture group
    (?!\. )  : negative lookahead asserts current position is not
               followed by a period followed by a space
    .        : match any character other than a line terminator
  )+         : end non-capture group and execute 1+ times
)            : end capture group 2

这使用了tempered greedy token 技术,该技术匹配一系列不以不需要的字符串开头的单个字符。例如,如果字符串是"concatenate"(?:(?:!cat).)+ 将匹配前三个字母但不匹配第二个'c',因此匹配将是'con'

【讨论】:

  • 感谢您的投入和努力@Cary Swoveland!对此,我真的非常感激。正则表达式中的匹配值直到字符串中的最后一个符号或描述中所述的下一个键才会出现
  • 我想我不明白“字符串中的最后一个符号”是什么意思。考虑到字符串仅包含字符,“符号”是什么意思?哪些字符是“符号”?问题中的示例可能没有以“字符串中的最后一个符号”终止的值。
【解决方案3】:

只是为了好玩,这里有一个 python,非正则表达式的解决方案:

latin = """[the sample input text]"""
new_lat = latin.replace(":","xxx:").split('xxx')
for l in new_lat:
    if ":" in l:        
        curr_ind = new_lat.index(l)
        cur_brek = l.rfind('. ')
        prev_brek = new_lat[curr_ind-1].rfind('. ')
        stub = new_lat[curr_ind-1][prev_brek+2:]
        new_l = stub+l[:cur_brek]
        print(new_l)

输出是从键开始的两个文本块。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-08
    • 1970-01-01
    • 2011-11-15
    • 2017-10-12
    • 2021-12-12
    • 1970-01-01
    • 2010-12-31
    相关资源
    最近更新 更多