十进制之前和/或之后的数字

时间:2018-05-07 22:53:26

标签: python regex python-3.x

我希望将模式digits.digitsdigits.[digits][digits].digits与Python中的正则表达相匹配。

此源:Postgres docs状态而不是数字常量可以采用以下任何形式:

digits
digits.[digits][e[+-]digits]
[digits].digits[e[+-]digits]
digitse[+-]digits

括号表示选项,digits是一个或多个数字,0-9。

我想匹配此语法的一小部分,

digits.[digits]
[digits].digits

换句话说,至少有一位必须在小数点之前或之后。 (或者,之前和之后。)

在字符串numbers = '.42 5.42 5. .'中,对re.findall(regex, numbers)的调用应返回['.42', '5.42', '5.']

我尝试的是if-then条件,(?(id/name)yes-pattern|no-pattern)

regex = r'(\d+)?(?(1)\.\d*|\.\d+)'

问题是,这需要一个捕获组,(1)引用,re.findall(r'(\d+)?(?(1)\.\d*|\.\d+)', numbers)提供['', '5', '5'],因为它抓住捕获组。

现在请忽略单词边界,前导零,指数表示法等。一个天真的正则表达式将是:

regex = r'\d+\.\d*|\d*\.\d+'

但是随着语法复杂性的增加,我不想仅仅| - 一起使用单独的正则表达式。

我如何构建这个以使re.findall(regex, numbers)返回上面的列表?

1 个答案:

答案 0 :(得分:2)

虽然您可以将正则表达式与re.finditer一起使用,以获得包含每个匹配值([x.group(0) for x in re.finditer(regex, numbers)])的第一个组,但您也可以获得所需的值

re.findall(r'(?=\.?\d)\d*\.\d*', s)

请参阅regex demo

<强>详情

  • (?=\.?\d) - 一个积极的前瞻,需要一个可选的.,后面紧跟当前位置右侧的数字
  • \d* - 0+位数
  • \. - 一个点
  • \d* - 0+位数

因此,即使消费模式中的\d*可以匹配0位数,前瞻也需要至少一个。

Python demo

import re
s=".42 5.42 5. ."
print(re.findall(r'(?=\.?\d)\d*\.\d*', s))
# => ['.42', '5.42', '5.']