【问题标题】:getting a set of numbers with regex in python在python中使用正则表达式获取一组数字
【发布时间】:2020-06-29 09:18:57
【问题描述】:

假设我有以下字符串

string = "serial 7's 93-86-79-72-65 very slow, recall 3/3 "

现在,我想在 Python 中使用正则表达式来查找数字集。请注意,数字 必须 前面有 "serial 7's" 我尝试了以下方法:

re.findall('(?<=serial 7\'s )(\d+, )', string)
re.findall('(?<=serial 7\'s )(\d+, )+', string)

似乎没有任何效果。请注意,我们尝试提取的整数数量可能未知。我只想要具有特定模式的数字。不是其他可能散布在文本中的数字。

预期输出:['93','86','79','72','65']

【问题讨论】:

  • 我希望我能接受多个答案。谢谢大家!

标签: python-3.x regex


【解决方案1】:

使用一个正则表达式的另一种方法:

import re

string = "serial 7's 93-86-79-72-65 very slow, recall 3/3 "

regex = r"(?<=serial 7's) (\d+-?)+"

matches = re.finditer(regex, test_str, re.MULTILINE)

for match in matches:
    integers = match.group(0).strip().split("-")

print(integers) # ['93', '86', '79', '72', '65']

【讨论】:

    【解决方案2】:

    我的两分钱,你可以使用下面的模式和re.search

    \bserial 7's\s(\d+(?:-\d+)*)
    

    import re
    s = "serial 7's 93-86-79-72-65 very slow, recall 3/3 "
    res = re.search(r"\bserial 7's\s(\d+(?:-\d+)*)", s)
    if res:
        print(res.group(1).split('-')) # ['93', '86', '79', '72', '65']
    else:
        print('No match')
    

    我会首先检查是否有任何匹配实际发生,其中模式必须包含数字,如果有多个值,则由连字符分隔。既然您提到了:“请注意,我们尝试提取的整数数量可能未知。我只想要具有特定模式的数字。”

    • \b - 字边界。
    • serial 7's - 从字面上匹配“序列 7”。
    • \s+ - 一个或多个空格字符。
    • ( - 打开捕获组。
    • \d+ - 至少匹配一个数字。
    • (?:-\d+)* - 零次或多次连字符后跟至少一个数字的非捕获组。
    • ) - 关闭捕获组。

    或者,可以使用regex 模块,并使用非固定宽度的正向后视:

    (?<=\bserial 7's\s+(?:\d+-)*)\d+
    

    import regex
    s = "serial 7's 93-86-79-72-65 very slow, recall 77 3/3 "
    lst = regex.findall(r"(?<=\bserial 7's\s+(?:\d+-)*)\d+", s)
    print(lst) # ['93', '86', '79', '72', '65']
    
    • (?&lt;= - 积极向后看的开始。
      • \b - 一个词的边界。
      • serial 7's - 字面意思是“序列 7”。
      • \s+ - 一个或多个空格字符。
      • (?: - 打开非捕获组。
        • \d+- - 至少匹配一个数字,后跟一个连字符。
        • )* - 关闭非捕获组并匹配它零次或多次。
      • ) - 积极向后看。
    • \d+ - 至少匹配一个数字。

    【讨论】:

      【解决方案3】:

      我会在这里使用re.findallsplit

      string = "serial 7's 93-86-79-72-65 very slow"
      matches = re.findall(r"\bserial 7's (\S+)", string)
      nums = matches[0].split('-')
      print(nums)
      

      打印出来:

      ['93', '86', '79', '72', '65']
      

      【讨论】:

      • 我可以知道\S 代表什么吗?我倾向于接受这个答案
      • \S+ 将匹配任何连续的非空白字符集合。在这种情况下,它匹配带连字符的数字单词。
      【解决方案4】:

      如果你可以使用regex module,你也可以使用\G\K

      (?:\bserial 7's |\G(?!^))-?\K\d+
      

      解释

      • (?:非捕获组
        • \bserial 7's 匹配序列号 7 和空格
        • |或者
        • \G(?!^) \G 锚在 2 个位置匹配:在字符串的开头,或在前一个匹配的结尾。我们不希望匹配从头开始,所以使用否定的前瞻来排除它。
      • )
      • -?\K 匹配可选 - 并重置匹配缓冲区(忘记匹配到现在的内容)
      • \d+匹配1+位数

      Regex demo | Python demo

      示例代码

      import regex
      
      pattern = r"(?:\bserial 7's |\G(?!^))-?\K\d+"
      string = "serial 7's 93-86-79-72-65 very slow, recall 3/3 "
      
      print(regex.findall(pattern, string))
      

      输出

      ['93', '86', '79', '72', '65']
      

      【讨论】:

        【解决方案5】:

        可以试试:

        
        string = "serial 7's 93-86-79-72-65 very slow"
        
        #Simple regex to find numbers
        reg = re.compile("\d+")
        
        #We want to find numbers on as short string as possible.
        #So, break the long the string into the part we need to search there..
        res = reg.findall(s.split("serial 7's")[1])
        
        print(res)
        >> ['93', '86', '79', '72', '65']
        

        【讨论】:

        • 如果输入字符串包含的数字不是出现在X-Y-Z 字符串中的数字,您的解决方案将失败
        【解决方案6】:

        使用 PyPi 正则表达式并捕获数字:

        import regex  # pip install regex
        string = "serial 7's 93-86-79-72-65 very slow, recall 3/3 "
        pattern = r"serial\s+7's\s+(?:-?(\d+))+"
        match = regex.search(pattern, string)
        if match:
            print(match.captures(1))
        # ['93', '86', '79', '72', '65']
        

        Python proof

        表达式解释

        --------------------------------------------------------------------------------
          serial                   'serial'
        --------------------------------------------------------------------------------
          \s+                      whitespace (\n, \r, \t, \f, and " ") (1 or
                                   more times (matching the most amount
                                   possible))
        --------------------------------------------------------------------------------
          7's                      '7\'s'
        --------------------------------------------------------------------------------
          \s+                      whitespace (\n, \r, \t, \f, and " ") (1 or
                                   more times (matching the most amount
                                   possible))
        --------------------------------------------------------------------------------
          (?:                      group, but do not capture (1 or more times
                                   (matching the most amount possible)):
        --------------------------------------------------------------------------------
            -?                       '-' (optional (matching the most amount
                                     possible))
        --------------------------------------------------------------------------------
            (                        group and capture to \1:
        --------------------------------------------------------------------------------
              \d+                      digits (0-9) (1 or more times
                                       (matching the most amount possible))
        --------------------------------------------------------------------------------
            )                        end of \1
        --------------------------------------------------------------------------------
          )+                       end of grouping
        

        【讨论】:

          猜你喜欢
          • 2021-12-17
          • 1970-01-01
          • 1970-01-01
          • 2016-09-14
          • 1970-01-01
          • 2018-07-21
          • 1970-01-01
          • 2023-03-16
          相关资源
          最近更新 更多