Python中如何使用正则表达式匹配数值类型字符串?
求表达式匹配 int 类型、float 类型,比如匹配 0、1.0、2,0.0000、123.345, 不匹配时间格式 2018-12-29、版本号 2.3.4。
Python中如何使用正则表达式匹配数值类型字符串?
目前用的“[0-9]+.?[0-9]+?$” ,不能匹配 0、1、2 等个位数的 int 类型。
import re
# 1. 匹配整数(包括正负数)
int_pattern = r'[-+]?\d+'
print(re.findall(int_pattern, "温度从-20升到+30度")) # ['-20', '+30']
# 2. 匹配浮点数(包含小数点)
float_pattern = r'[-+]?\d+\.\d+'
print(re.findall(float_pattern, "价格是12.5元和-3.14元")) # ['12.5', '-3.14']
# 3. 匹配科学计数法数值
sci_pattern = r'[-+]?\d+(?:\.\d+)?[eE][-+]?\d+'
print(re.findall(sci_pattern, "1.23e-4和5E+6")) # ['1.23e-4', '5E+6']
# 4. 综合匹配所有数值类型(最常用)
number_pattern = r'[-+]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][-+]?\d+)?'
text = "数据: 42, -3.14, +0.5, .618, 1e10, -2.5E-3"
print(re.findall(number_pattern, text)) # ['42', '-3.14', '+0.5', '.618', '1e10', '-2.5E-3']
# 5. 如果需要捕获分组信息
compiled = re.compile(r'([-+]?)(\d+(?:\.\d*)?|\.\d+)(?:[eE]([-+]?\d+))?')
match = compiled.match("-1.23e-4")
if match:
print(f"符号: {match.group(1)}") # -
print(f"数值: {match.group(2)}") # 1.23
print(f"指数: {match.group(3)}") # -4
核心要点:
[-+]?匹配可选正负号(?:\d+(?:\.\d*)?|\.\d+)匹配整数/小数(包括.5形式)(?:[eE][-+]?\d+)?匹配可选的科学计数法部分- 用
re.findall()提取所有匹配,re.search()找第一个匹配
建议:根据具体需求选择合适模式。
加个 | 匹配个位数规则?
我就问下,版本号 2.3 你怎么和 float 2.3 区分 /dog
/^([0-9].)?[0-9]+$/
把 [0-9] 换成 [0-9]+ 可以不匹配 .1, .25 这样的浮点数
\d+.{0,1}\d*
如果你不考虑范围、只考虑 C99 的字面量、不考虑类型后缀的话:
整数是
(1-9)(0-9)|0[xX][0-9A-Fa-f]+|0(0-7)
第一种是十进制,第二种是十六进制,第三种是八进制。
浮点数是
0xX[pP][±]?[0-9]+|[0-9]+[eE][±]?[0-9]+|([0-9]+.[0-9]*|.[0-9]+)([eE][±]?[0-9]+)?
第一种是十六进制,第二种是十进制没有小数点,第三种是十进制有小数点。
提示:正负号是一元运算,而不是字面量的一部分。
你这么一说,我竟无言以对,幸好我只是做 mysql 监控指标采集,mysql 的版本号不会为 2.3 这种的。🙈
这个不需要用正则表达式,float(“xxx”) 没异常就匹配了。
是个好方法,已经测试可以,但是我想更简单点。
\d+(.\d+)?
正经脸,是不是也太简单了……你是不是连去网上搜一下正则的教程的时间也没有……
#6 Oops 整数应该是
[1-9][0-9]|0[xX][0-9A-Fa-f]+|0[0-7]
感谢,这个答案试过了,可以。🎉🎉🎉
考虑的很周到,但是您的表达式不能过滤版本号,我这边采集的数据都是十进制的。
[^-](\d+([.\d]\d+)[^-]
是实话,我 google 了好多呢,您的表达式不能过滤时间格式,我之前也试过。
您的也是不能过滤时间格式。🙈🙈🙈
(?<![\d.-])(\d+.?\d*)(?![\d.-])
刚刚写的 自测通过~
时间格式里有三个数字,简单匹配当然能匹配上。这得看你其他限制啊,比如是空格中间的一段值吗还是什么?
这确实是个好方式,但是有的值是空字符串,如果强行用 float 的话,值就会变成 0.0,但是值对应的指标类型不为数值类型,所以也不能强制转换,除非再加一层类型判断,这样的话,感觉还是正则方便。
嗯,是的,不好意思。那你知道为什么我的答案能匹配日期吗?~ 2333
>>> float("")
Traceback (most recent call last):
File “<stdin>”, line 1, in <module>
ValueError: could not convert string to float:
#12 这个答案是必须数字开头结尾的啊~
时间格式我没描述清楚,应该是 2018-12-28 15:58:48 这种。
刚回复被限制,当然知道原因啊🤣
那您这个方案是行的通的,我大意了。
是的呢
#13 你可以用断言排除所有的日期的情况,或者你可以先删除所有的日期、版本号。
你的提问非常模糊,因此大家只能靠 psychic helping.
不知道楼主是想要学习正则表达式呢,还是要满足需求?
实际上根本用不着正则。
>>> text = “比如匹配 0、1.0、2,0.0000、123.345, 不匹配时间格式 2018-12-29、版本号 2.3.4。”
>>> [ ‘’.join(g) for k,g in itertools.groupby(text, lambda x: x in ‘0123456789.-:’) if k]
[‘0’, ‘1.0’, ‘2’, ‘0.0000’, ‘123.345’, ‘2018-12-29’, ‘2.3.4’]
>>> list(filter(lambda y: (’-’ not in y) and (y.count(’.’) < 2), [‘0’, ‘1.0’, ‘2’, ‘0.0000’, ‘123.345’, ‘2018-12-29’, ‘2.3.4’]))
[‘0’, ‘1.0’, ‘2’, ‘0.0000’, ‘123.345’]
>>>

测试下图床,今天很想贴图片,但是没有图床,自己搭建了一个~
\d+(?:.\d+)*


