V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
wdc63
V2EX  ›  正则表达式

求给生成一个正则表达式,年龄大了,脑子不够用了

  •  
  •   wdc63 · 2022-06-25 01:46:56 +08:00 · 2014 次点击
    这是一个创建于 643 天前的主题,其中的信息可能已经有所发展或是发生改变。

    1 必须是合法数字(前面不能多个 0 ) 2 范围必须在-1000 到 1000 之间(包括-1000 和 1000 ) 3 可以是整数,可以是小数,如果是小数位数必须小于等于两位

    例如 0.001 、9999 、-1.010 、01.32 不合法 99.99 、0 、-1.2 合法

    24 条回复    2022-06-25 20:46:25 +08:00
    golangLover
        1
    golangLover  
       2022-06-25 01:54:01 +08:00 via Android
    如果这个东西难以表达,那根本不应该用正则
    wdc63
        2
    wdc63  
    OP
       2022-06-25 01:56:35 +08:00
    @golangLover 老大说正则效率最高,考虑正则优先,我也想写几条 if else ,实在不好搞就算了吧
    ETiV
        3
    ETiV  
       2022-06-25 02:01:49 +08:00
    试着玩了玩。。。

    正则

    ^-?(((?!0+)1?[0-9]{0,3})|0)(\.[0-9]{1,2})?$

    以及在 regex101 上的 test case
    https://regex101.com/r/2gbObg/1
    ETiV
        4
    ETiV  
       2022-06-25 02:03:12 +08:00
    658 steps, 0.2ms

    整体来看效率并不高 🤣(小心 RegEx DoS 攻击)
    autoxbc
        5
    autoxbc  
       2022-06-25 02:14:09 +08:00   ❤️ 3
    正则被广泛使用的原因是它是线性书写的语言,没有任何结构,也就可以在无需约定结构的前提下,在各种高级语言中嵌入

    这个优点也正是正则的缺点,因为没有结构,在人类可读的范围内,表达力严重受限,完全无法和有控制流的高级语言相比

    所以正则的场景就是稍微浅浅的用一下,如果普通水准的程序员无法顺利写出来,那么最终写出来了别人也无法顺利读懂
    zjp
        6
    zjp  
       2022-06-25 02:27:57 +08:00 via Android
    ^-?(0|1000|[1-9]\d{0,2}(?:\.\d{1,2})?)$
    https://regexr.com/6offc
    确定是数字的情况肯定 if else 更高
    而且你能确定这些表达式没有问题吗
    jfcherng
        7
    jfcherng  
       2022-06-25 02:33:02 +08:00
    如樓樓上所說的,不解釋的話你很可能得花很多時間才能看懂在寫什麼,或是根本看不懂。
    https://regex101.com/r/yKSTiy/1
    zjp
        8
    zjp  
       2022-06-25 02:33:43 +08:00 via Android
    @zjp 果然 括号括错了
    https://regex101.com/r/lf70Du/2 (用了#3 的测试用例
    gam2046
        9
    gam2046  
       2022-06-25 02:36:24 +08:00
    ^-?(?:[1-9]{1,1}\d{0,}|0)(?:\.\d{0,}[^0]|)$

    但是可读性真的很差,而且速度也不快。

    怀疑可能是 X-Y 问题,多数情况下可以利用语言提供的 parseInt/parseFloat 一类的方法来处理,但是又要排除 01.32 这种情况,着实有点奇怪。
    darklights
        10
    darklights  
       2022-06-25 03:56:48 +08:00
    3 楼和 8 楼的大佬给出的已经很接近了,但还是有例外( 1000.99 )

    不建议用正则处理这类多重逻辑的问题,可读性是其次,要考虑到所有可能的情况才是最伤脑细胞的,然而几个 if else 就能解决。用合适工具解决合适问题。
    muhuan
        11
    muhuan  
       2022-06-25 07:29:25 +08:00
    ^-?(((([1-9][0-9]{0,2})|0)(\.[0-9]{1,2})?)|(1000))$
    Mutoo
        12
    Mutoo  
       2022-06-25 07:46:46 +08:00
    Mutoo
        13
    Mutoo  
       2022-06-25 08:04:12 +08:00
    https://rulex-rs.github.io/playground/

    # -1000 ~ 1000
    ['-+']?
    %
    range '0'-'1000'
    ('.' ['0'-'9']+)?
    %


    to javascript:

    [\-+]?\b(?:0|1(?:0(?:00?|[1-9])?|[1-9][0-9]?)?|[2-9][0-9]{0,2})(?:\.[0-9]+)?\b
    Mutoo
        14
    Mutoo  
       2022-06-25 08:06:41 +08:00
    忘了处理两位小数了,不过用 rulex 语法还是很容易写出来的。有兴趣可以自己试试
    cpstar
        15
    cpstar  
       2022-06-25 08:44:55 +08:00
    既然是数字,为什么偏要用字符串的处理方式?还断言效率高??
    1. ""+(x*1)==""+x
    2. -1000≤(x*1)≤1000
    3. x.indexOf(".")==-1||x.length-x.indexOf(".")-1≤2
    这不比正则快?写正则折腾半天,解析正则折腾半天。
    snw
        16
    snw  
       2022-06-25 09:02:34 +08:00 via Android
    正则效率高是针对字符串简单规则,而且需要经验不然很容易踩坑。你这种数字需求并不适合用正则。
    snw
        17
    snw  
       2022-06-25 09:18:11 +08:00 via Android
    对了,如果科学计数法参合进来就更烧脑了。
    1.
    .1
    +1
    1E2
    1e2
    1e+2
    1.e+2
    1.000e+2
    1e-2
    -1e2
    Tink
        18
    Tink  
       2022-06-25 12:09:45 +08:00 via Android
    费脑子
    Nasei
        19
    Nasei  
       2022-06-25 12:32:20 +08:00
    ^-?(([1-9]\d{0,2}|0)(\.\d\d)?|1000)$
    cheng6563
        20
    cheng6563  
       2022-06-25 13:21:00 +08:00
    正则不适合用来比较数字大小
    wdc63
        21
    wdc63  
    OP
       2022-06-25 15:53:25 +08:00
    @ETiV 谢谢,我也测试一下 if else 看看哪个快
    wdc63
        22
    wdc63  
    OP
       2022-06-25 15:55:20 +08:00
    @cpstar 获取用户的输入框,不确定是数字,就是用正则来写一个输入框的 validation ,但是在服务器上运行,不在本地运行。
    wdc63
        23
    wdc63  
    OP
       2022-06-25 15:56:40 +08:00
    谢谢各位, 昨晚睡了没及时回复,在此不再一一道谢。
    cpstar
        24
    cpstar  
       2022-06-25 20:46:25 +08:00
    OP 22#,所以你看我把 x 当成字符串处理了,x*1 才是数字型。服务器上运行也可以啊,只不过不想 javascript 那种弱类型,比如 Float.parseFloat(),多几道手续而已。

    另外 H5 提供了<input type="number" name="marks" min="-1000.00" max="1000.00" step="0.01">

    我觉得如果非要限定某种方法解决问题,那实际上就并不是在解决问题,而在钻牛角尖。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3676 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 00:13 · PVG 08:13 · LAX 17:13 · JFK 20:13
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.