【问题标题】:Regex to extract one or two values from text正则表达式从文本中提取一两个值
【发布时间】:2021-02-15 07:30:38
【问题描述】:

我正在尝试构建一个正则表达式(在 python 中)以从文本文档中提取一个或两个值。要匹配的模式将始终采用以下形式:

<div>SCORE: x to y<\/div>

其中 x 和 y 可以介于 -7 和 + 6 之间。有时只会出现一个数字。如果有两个数字,我需要同时捕获这两个数字。此外,“to”可能缺少逗号或破折号,甚至“too”!空白是可变的。所以我需要类似的东西,

x,y=re.findall('<div>SCORE: (-+?[0-5])[a-zA-Z]?(-+?[0-5]?)<\/div>', text)

除了这显然是不正确的。任何指导表示赞赏。

示例包括

<div>SCORE: 0</div>
<div>SCORE: 0 to 5</div>
<div>SCORE: -1 to 6</div>
<div>SCORE: -1 to -3</div>
<div>SCORE: -4</div>
<div>SCORE: 3</div>

【问题讨论】:

    标签: python python-3.x regex


    【解决方案1】:

    其中 x 和 y 可以介于 -7+6 之间。有时只会出现一个数字。如果有两个数字,我需要同时捕获这两个数字。 to 也可能缺少逗号或破折号,甚至 too!空白是可变的。

    你可以试试这个正则表达式:

    <div>SCORE:\s*([+-]?[1-6]|-7|0)(?:\s*(?:[-,]|too?)\s*([+-]?[1-6]|-7|0))?</div>
    

    RegEx Demo

    RexEx 解释:

    • &lt;div&gt;SCORE::匹配&lt;div&gt;SCORE:文字
    • \s*: 0 个或多个空格
    • ([+-]?[1-6]|-7|0):匹配-7+6 之间的第一个数字并在#1 组中捕获
    • (?:: 启动非捕获组
      • \s*: 0 个或多个空格
      • (?:[-,]|too?):匹配 -,to
      • \s*: 0 个或多个空格
      • ([+-]?[1-6]|-7|0):匹配-7+6 之间的第一个数字并在组#2 中捕获
    • )?`: 结束可选非捕获组#1
    • &lt;/div&gt;:比赛结束&lt;/div&gt;

    【讨论】:

    • 谢谢你的解释!
    【解决方案2】:

    您可以为预期的数字格式编写一个正则表达式,然后再编写一个正则表达式来描述它们嵌入的测试结构:

    number_regex = r'-[1-7]|0|[1-6]|\+[1-6]'  # numbers between -7 to 6
    regex = r'<div>SCORE:\s*({0})\s+\w+\s+({0})\s*<\/div>'.format(number_regex)
    occurrences = re.findall(regex, text)
    

    基本上,您将感兴趣的文本描述为&lt;div&gt;&lt;/div&gt; 之间的字符串,其序列由一个数字、一个单词和另一个数字组成,由一些空格分隔。

    如果text 是:

    text = (
        "<div>SCORE: 5 to 6</div>"
        "<div>SCORE: 0 to 6</div>"
        "<div>SCORE: -7 to 6</div>"
        "<div>SCORE: -7 to -2</div>"
        "<div>SCORE:0 to +2</div>"
        "<div>SCORE:hi to 1</div>"
    )
    

    你得到:

    [('5', '6'), ('0', '6'), ('-7', '6'), ('-7', '-2'), ('0', '+2')]
    

    【讨论】:

      【解决方案3】:

      假设xy 之间的分隔符始终是一组连续的非空白字符,则以下模式应该有效:

      <div>SCORE:\s*(\S+)\s+\S+\s+(\S+)\s*<\/div>
      

      我们可以在这里使用re.findall

      inp = "<div>SCORE: x to y</div>"
      matches = re.findall(r'<div>SCORE:\s*(\S+)\s+\S+\s+(\S+)\s*<\/div>', inp)
      print(matches)  # [('x', 'y')]
      

      【讨论】:

        猜你喜欢
        • 2014-08-26
        • 2017-10-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-04-30
        • 2016-10-24
        • 1970-01-01
        相关资源
        最近更新 更多