V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
jarry118
V2EX  ›  Python

正则表达式匹配数值类型字符串

  •  
  •   jarry118 · 2018-12-29 08:44:28 +08:00 · 2896 次点击
    这是一个创建于 2187 天前的主题,其中的信息可能已经有所发展或是发生改变。

    求表达式匹配 int 类型、float 类型,比如匹配 0、1.0、2,0.0000、123.345, 不匹配时间格式 2018-12-29、版本号 2.3.4。

    32 条回复    2018-12-29 17:28:10 +08:00
    jarry118
        1
    jarry118  
    OP
       2018-12-29 08:46:42 +08:00
    目前用的“[0-9]+\.?[0-9]+?$” ,不能匹配 0、1、2 等个位数的 int 类型。
    wersonliu9527
        2
    wersonliu9527  
       2018-12-29 08:58:06 +08:00   ❤️ 1
    加个 | 匹配个位数规则?
    jinhan13789991
        3
    jinhan13789991  
       2018-12-29 09:03:23 +08:00
    我就问下,版本号 2.3 你怎么和 float 2.3 区分 /dog
    bumz
        4
    bumz  
       2018-12-29 09:03:32 +08:00
    /^([0-9]*\.)?[0-9]+$/

    把 [0-9]* 换成 [0-9]+ 可以不匹配 .1, .25 这样的浮点数
    yeyu1989
        5
    yeyu1989  
       2018-12-29 09:05:37 +08:00
    \d+\.{0,1}\d*
    geelaw
        6
    geelaw  
       2018-12-29 09:07:08 +08:00
    如果你不考虑范围、只考虑 C99 的字面量、不考虑类型后缀的话:

    整数是
    (1-9)(0-9)*|0[xX][0-9A-Fa-f]+|0(0-7)*

    第一种是十进制,第二种是十六进制,第三种是八进制。

    浮点数是

    0[xX]([0-9A-Fa-f]+(\.[0-9a-fA-F]*)?|\.[0-9a-fA-F]+)[pP][+-]?[0-9]+|[0-9]+[eE][+-]?[0-9]+|([0-9]+\.[0-9]*|\.[0-9]+)([eE][+-]?[0-9]+)?

    第一种是十六进制,第二种是十进制没有小数点,第三种是十进制有小数点。

    提示:正负号是一元运算,而不是字面量的一部分。
    jarry118
        7
    jarry118  
    OP
       2018-12-29 09:07:31 +08:00
    @jinhan13789991 你这么一说,我竟无言以对,幸好我只是做 mysql 监控指标采集,mysql 的版本号不会为 2.3 这种的。🙈
    goreliu
        8
    goreliu  
       2018-12-29 09:08:00 +08:00
    这个不需要用正则表达式,float("xxx") 没异常就匹配了。
    jarry118
        9
    jarry118  
    OP
       2018-12-29 09:08:09 +08:00
    @wersonliu9527 是个好方法,已经测试可以,但是我想更简单点。
    szq8014
        10
    szq8014  
       2018-12-29 09:09:11 +08:00
    \d+(\.\d+)?

    正经脸,是不是也太简单了……你是不是连去网上搜一下正则的教程的时间也没有……
    geelaw
        11
    geelaw  
       2018-12-29 09:09:45 +08:00
    @geelaw #6 Oops 整数应该是

    [1-9][0-9]*|0[xX][0-9A-Fa-f]+|0[0-7]*
    jarry118
        12
    jarry118  
    OP
       2018-12-29 09:11:59 +08:00
    @bumz 感谢,这个答案试过了,可以。🎉🎉🎉
    jarry118
        13
    jarry118  
    OP
       2018-12-29 09:15:41 +08:00
    @geelaw 考虑的很周到,但是您的表达式不能过滤版本号,我这边采集的数据都是十进制的。
    Leigg
        14
    Leigg  
       2018-12-29 09:17:14 +08:00 via iPhone
    [^-](\d+([\.\d]\d+)[^-]
    jarry118
        15
    jarry118  
    OP
       2018-12-29 09:17:44 +08:00
    @szq8014 是实话,我 google 了好多呢,您的表达式不能过滤时间格式,我之前也试过。
    jarry118
        16
    jarry118  
    OP
       2018-12-29 09:19:49 +08:00
    @yeyu1989 您的也是不能过滤时间格式。🙈🙈🙈
    jinhan13789991
        17
    jinhan13789991  
       2018-12-29 09:22:05 +08:00
    (?<![\d\.-])(\d+\.?\d*)(?![\d\.-])
    刚刚写的 自测通过~
    yeyu1989
        18
    yeyu1989  
       2018-12-29 09:24:11 +08:00
    @jarry118 时间格式里有三个数字,简单匹配当然能匹配上。这得看你其他限制啊,比如是空格中间的一段值吗还是什么?
    jarry118
        19
    jarry118  
    OP
       2018-12-29 09:25:35 +08:00
    @goreliu 这确实是个好方式,但是有的值是空字符串,如果强行用 float 的话,值就会变成 0.0,但是值对应的指标类型不为数值类型,所以也不能强制转换,除非再加一层类型判断,这样的话,感觉还是正则方便。
    szq8014
        20
    szq8014  
       2018-12-29 09:25:42 +08:00
    @jarry118 嗯,是的,不好意思。那你知道为什么我的答案能匹配日期吗?~ 2333
    goreliu
        21
    goreliu  
       2018-12-29 09:29:02 +08:00
    @jarry118

    >>> float("")
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    ValueError: could not convert string to float:
    jinhan13789991
        22
    jinhan13789991  
       2018-12-29 09:41:41 +08:00
    @jarry118 #12 这个答案是必须数字开头结尾的啊~
    bzw875
        23
    bzw875  
       2018-12-29 09:50:51 +08:00   ❤️ 1
    jarry118
        24
    jarry118  
    OP
       2018-12-29 10:42:34 +08:00
    @yeyu1989 时间格式我没描述清楚,应该是 2018-12-28 15:58:48 这种。
    jarry118
        25
    jarry118  
    OP
       2018-12-29 10:43:47 +08:00
    @szq8014 刚回复被限制,当然知道原因啊🤣
    jarry118
        26
    jarry118  
    OP
       2018-12-29 10:44:39 +08:00
    @goreliu 那您这个方案是行的通的,我大意了。
    jarry118
        27
    jarry118  
    OP
       2018-12-29 10:45:10 +08:00
    @bzw875 感谢!🎉🎉🎉
    jarry118
        28
    jarry118  
    OP
       2018-12-29 10:45:34 +08:00
    @jinhan13789991 是的呢
    geelaw
        29
    geelaw  
       2018-12-29 11:02:29 +08:00
    @jarry118 #13 你可以用断言排除所有的日期的情况,或者你可以先删除所有的日期、版本号。

    你的提问非常模糊,因此大家只能靠 psychic helping.
    xpresslink
        30
    xpresslink  
       2018-12-29 14:46:38 +08:00
    不知道楼主是想要学习正则表达式呢,还是要满足需求?
    实际上根本用不着正则。

    >>> 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']
    >>>
    jinhan13789991
        31
    jinhan13789991  
       2018-12-29 17:24:39 +08:00
    ![cmd-markdown-logo]( http://35.220.239.255:8080/uploads/big/47fa4fd2e562a111acd32f512487e3e4.png)

    测试下图床,今天很想贴图片,但是没有图床,自己搭建了一个~
    Vegetable
        32
    Vegetable  
       2018-12-29 17:28:10 +08:00
    \d+(?:\.\d+)*
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1137 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 18:32 · PVG 02:32 · LAX 10:32 · JFK 13:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.