首页 > 解决方案 > 小数点前和/或小数点后的数字

问题描述

我想用 Python 中的正则表达式匹配模式digits.digits、、digits.[digits]和。[digits].digits

来源:Postgres 文档状态比数字常量可以采用以下任何一种形式:

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)返回上面的列表?

标签: pythonregexpython-3.x

解决方案


虽然您可以使用正则表达式re.finditer来获取具有每个完整匹配值 ( [x.group(0) for x in re.finditer(regex, numbers)]) 的第一组,但您也可以使用

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

查看正则表达式演示

细节

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

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

Python演示

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

推荐阅读