【问题标题】:Python Regex match all occurrences of decimal pattern followed by another patternPython Regex 匹配所有出现的十进制模式,后跟另一个模式
【发布时间】:2016-06-24 22:38:46
【问题描述】:

我进行了很多搜索,包括this SO post,这几乎对我有用。

我正在处理一个 huge 字符串,试图捕获出现在一系列十进制模式之后和字母数字单词之前的四位数字组。

还有其他四位数字组不符合条件,因为它们前面有单词或其他数字模式。

编辑:我的字符串不是多行的,只是为了方便显示在这里。

例如:

>> my_string = """BEAVER COUNTY 001 0000 
1010 BEAVER 
2010 BEAVER COUNTY SCH DIST 
0.008504 
...(more decimals)
0.008508 
4010 COUNTY SPECIAL SERVICE DIST NO.1   <---capture this 4010
4040 BEAVER COUNTY 
8005 GREENVILLE SOLAR
0.004258 
0.008348 
...(more decimals)
0.008238 
4060 SPECIAL SERVICE DISTRICT NO 7   <---capture this 4060
"""

理想的re.findall 应该返回:

['4010','4060']

以下是我尝试过但缺少的模式:

re.findall(r'(?=(\d\.\d{6}\s+)(\s+\d{4}\s))', my_string)
# also tried         
re.findall("(\s+\d{4}\s+)(?:(?!^\d+\.\d+)[\s\S])*", my_string)
# which gets me a little closer but I'm still not getting what I need.

提前致谢!

【问题讨论】:

标签: python regex


【解决方案1】:

单行字符串方法:

只需匹配浮点数就在 4 个独立数字之前:

r'\d+\.\d+\s+(\d{4})\b'

this regex demo

Python demo:

import re
p = re.compile(r'\d+\.\d+\s+(\d{4})\b')
s = "BEAVER COUNTY 001 0000 1010 BEAVER 2010 BEAVER COUNTY SCH DIST 0.008504 0.008508 4010 COUNTY SPECIAL SERVICE DIST NO.1 4040 BEAVER COUNTY 8005 GREENVILLE SOLAR 0.004258 0.008348 0.008238 4060 SPECIAL SERVICE DISTRICT NO 7"
print(p.findall(s))
# => ['4010', '4060']

原始答案:多行字符串

您可以使用正则表达式检查上一行的浮点值,然后在下一行捕获独立的 4 位数字:

re.compile(r'^\d+\.\d+ *[\r\n]+(\d{4})\b', re.M)

regex demo here

模式说明

  • ^ - 行首(使用re.M
  • \d+\.\d+ - 1 个以上数字,. 和 1 个或多个数字
  • * - 零个或多个空格(替换为 [^\S\r\n] 以仅匹配水平空格)
  • [\r\n]+ - 1 个或多个 LF 或 CR 符号(仅限于 1 个换行符,替换为 (?:\r?\n|\r)
  • (\d{4})\b - 由 re.findall 返回的组 1 匹配 4 位数字,后跟单词边界(非数字、非字母、非_)。

Python demo:

import re
p = re.compile(r'^\d+\.\d+ *[\r\n]+(\d{4})\b', re.MULTILINE)
s = "BEAVER COUNTY 001 0000 \n1010 BEAVER \n2010 BEAVER COUNTY SCH DIST \n0.008504 \n...(more decimals)\n0.008508 \n4010 COUNTY SPECIAL SERVICE DIST NO.1   <---capture this 4010\n4040 BEAVER COUNTY \n8005 GREENVILLE SOLAR\n0.004258 \n0.008348 \n...(more decimals)\n0.008238 \n4060 SPECIAL SERVICE DISTRICT NO 7   <---capture this 4060"
print(p.findall(s)) # => ['4010', '4060']

【讨论】:

  • 这太棒了!我没有在我的原始帖子中提到我为方便起见制作了字符串多行。如果不是多线,它会改变很多吗?我将编辑 OP 以显示这一点。
  • 这只是一个巨大的正在进行的字符串,还没有行。我正在尝试使用这个正则表达式来创建做re.split的地方。
  • 它会改变的,哦,是的。
  • 我刚想到没有必要匹配所有的浮点数:)
【解决方案2】:

这将对您有所帮助:

"((\d+\.\d+)\s+)+(\d+)\s?(?=\w+)"gm

使用第三组表示\3

Demo And Explaination

【讨论】:

    【解决方案3】:

    试试这个模式:

    re.compile(r'(\d+[.]\d+)+\s+(?P<cap>\d{4})\s+\w+')
    

    我写了一个小代码并检查了它,它可以工作。

    import re
    
    p=re.compile(r'(\d+[.]\d+)+\s+(?P<cap>\d{4})\s+\w+')
    
    my_string = """BEAVER COUNTY 001 0000 
    1010 BEAVER 
    2010 BEAVER COUNTY SCH DIST 
    0.008504 
    ...(more decimals)
    0.008508 
    4010 COUNTY SPECIAL SERVICE DIST NO.1   <---capture this 4010
    4040 BEAVER COUNTY 
    8005 GREENVILLE SOLAR
    0.004258 
    0.008348 
    ...(more decimals)
    0.008238 
    4060 SPECIAL SERVICE DISTRICT NO 7   <---capture this 4060
    """
    
    s=my_string.replace("\n", " ")
    
    match=p.finditer(s)
    
    for m in match:
        print m.group('cap')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-09
      • 2020-02-09
      • 2015-06-18
      • 2013-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多