使用正则表达式提取数字

时间:2019-10-07 12:38:55

标签: python regex python-3.x

如何从string提取数字表达式,其中可能没有underscorehyphen。例如例如2016-032016_03或简单地201603

示例字符串:

s = 'Total revenue for 2016-03 is 3000 €'  # Output 2016-03
s = 'Total revenue for 2016_03 is 3000 €'  # Output 2016_03
s = 'Total revenue for 201603 is 3000 €'   # Output 201603

有6个数字,如果我们有-_,那么总长度为7。整个字符串中没有其他number

我不知道如何在if-else中使用regex,因此in可以包含长度为6或7的逻辑。对于像201603这样的简单字符串,我能够做到-

import re
print(re.findall('\d{6}','Total revenue for 201603 is 3000 €'))
['201603']

print(re.findall('\d{6}','Total revenue for 2016-03 is 3000 €'))
[]

注意:我正在寻找一种解决方案,理论上_-可以在6个长度数字之间的任意位置。像123-45612345612345-6等。

4 个答案:

答案 0 :(得分:2)

有两种方法:一种更具可读性,首先将字符串分割,然后获取与所需模式匹配的第一项,或者采用单个正则表达式则较不易理解。

请参见Python demo

import re
s = 'Total revenue for 201603 is 3000 €'
rx = re.compile(r'^(?=\d+(?:[_-]\d+)?$)[\d_-]{6,7}$')
res = [x for x in s.split() if rx.search(x)]
if len(res):
    print(res[0])

# Pure regex approach:
rx = re.compile(r'(?<!\S)(?=\d+(?:[_-]\d+)?(?!\S))[\d_-]{6,7}(?!\S)')
res = rx.search(s)
if res:
    print(res.group())

因此,在第一种方法中,将字符串用空格分开,并将^(?=\d+(?:[_-]\d+)?$)[\d_-]{6,7}$模式应用于每个项目,如果有匹配项,则返回第一个。模式匹配:

  • ^-字符串的开头
  • (?=\d+(?:[_-]\d+)?$)-一个正向超前查询,可确保有1个以上的数字,然后是_-,然后是1个以上的数字,直到字符串的末尾,
  • [\d_-]{6,7}-匹配6或7位数字,-_
  • $-字符串的结尾。

第二种方法仅涉及正则表达式,^锚点用(?<!\S)代替,$则用(?!\S)代替,它们充当空白边界。 (?<!\S)是负向查找,需要在当前位置之前留一个空格或字符串的开头,(?!\S)是负向查找,需要在当前位置后紧跟空白或字符串的结尾。

答案 1 :(得分:1)

如果您确定所需的值始终遵循标准模式,则可以使用正向后视

(?<=^Total revenue for )\d+[-_]?\d+
  • (?<=^Total revenue for )-匹配必须以Total revenue for开头,^从字符串开头开始
  • \d+-匹配一位或多位数字
  • [-_]?-匹配- or _(可选)

Regex Demo


或者,如果不确定所需的值格式,则可以以上述方式扩展上述正则表达式

(?<=^Total revenue for )(?=\d+[-_]?\d+)[\d_-]{6,7}(?!\S)
  • (?=\d+[-_]?\d+)-确保digit followed by - or _ optional followed by digit
  • [\d_-]{6,7}-匹配digit or - or _, 6 or 7 times
  • (?!\S)-不应后跟非空格字符

Regex Demo

答案 2 :(得分:0)

这应该相当简单:

 this.jsPlumbInstance.bind("connection", function(asda,originalEvent) {
  var connection = asda.connection;
  console.log(connection)

具体来说,这是“四位数,后跟print(re.findall(r'\d{4}[-_]?\d{2}', 'Total revenue for 201603 is 3000 €')) # ['201603'] '-'出现零或一,然后再出现两位数”。如果没有连字符或下划线,则四位数和两位数的结果与要求六位数的结果相同。

可以捕获连字符或下划线(如果有的话),所以您可以做的一件事就是将其过滤掉:

'_'

请注意,这是最不打扰您原始正则表达式的解决方案,它将在字符串的任何位置搜索这种“四位数字,然后是分隔符,然后再两位数字”的模式。如果您想将其限制为正试图查找的字符串,而忽略相似的字符串,则可能需要使正则表达式更具体。另请参见the re documentation

答案 3 :(得分:0)

您的正则表达式如下: 以空格开头,至少一个数字的序列,以空格结尾。 涉及到这一点:

\s(\d*)\s

在这里检查: https://regex101.com/r/V4NzLj/1