V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zzlit
V2EX  ›  程序员

求助一个数字输入的正则表达式

  •  
  •   zzlit · 297 天前 · 2155 次点击
    这是一个创建于 297 天前的主题,其中的信息可能已经有所发展或是发生改变。

    需要满足

    1. 00 这种情况不出现输入的时候只展示 0
    2. 01 这种情况展示 1
    3. 0.1 可以出现 现在写了一个正则如下,可以满足前两点,匹配上就后面的替换掉前面的,但是一加上小数点情况就多起来了,怎么写都不太对,求大佬帮帮忙。
    const reg = /(?<=^0)\d+/g;
    
    第 1 条附言  ·  296 天前
    感谢大佬们的解答给我提供了很多的思路,各个正则我也都试了去理解是什么含义,确实只有多用才能熟练。我的解答也是借鉴了大佬们的回答,最终拆成了两步来走,容易理解一点,应该基本就是这样了。

    最后再次感谢大家热情解答~
    ```
    <input type="text" id="input" />


    function removeLeadingZero(num) {
    const regex = /^([+-]?)0+(?=\d)/g;
    return num.replace(regex, '$1');
    }
    function limitNumberDot(num) {
    const regex = /^\d+\.?\d{0,2}/g;
    const matchResult = num.match(regex);
    if (matchResult) return matchResult[0];
    return num;
    }
    const input = document.getElementById('input');
    input.addEventListener('input', function () {
    const v = input.value;
    input.value = limitNumberDot(removeLeadingZero(v));
    });
    ```
    31 条回复    2023-06-05 18:27:54 +08:00
    littlepanic72
        1
    littlepanic72  
       297 天前
    [-+]?\b[0-9]*\.?[0-9]+\b regexbuddy 从这个软件找出来的... 安利一个
    littlepanic72
        2
    littlepanic72  
       297 天前
    @littlepanic72 好像不行...
    zhzy
        3
    zhzy  
       297 天前
    其实写不明白的话, 可以考虑不用正则来做吧...
    dreasky
        4
    dreasky  
       297 天前
    parseFloat 不就得了
    masellum
        5
    masellum  
       297 天前
    这需求不用正则也可以,写成显式的逻辑还更好维护,何必麻烦自己一定要上正则。
    Alias4ck
        6
    Alias4ck  
       297 天前
    xiayushengfan
        7
    xiayushengfan  
       297 天前
    chatgpt
    Alias4ck
        8
    Alias4ck  
       297 天前
    xiayushengfan
        9
    xiayushengfan  
       297 天前
    ^(0|[1-9]\d*)(\.\d+)?$
    GzhiYi
        10
    GzhiYi  
       297 天前
    有点像是强制输入数值型,比如说价格这种需求。同意楼上说的,获取输入字符后,走 if else 判断一些特殊的输入,最后再走合适的正则。
    dinghmcn
        11
    dinghmcn  
       297 天前
    参考 #4 楼的做法,大学的时候做计算器,就解决过类似的问题;使用保存都使用浮点型显示的时候转换成字符串
    Ashore
        12
    Ashore  
       297 天前
    /^0*(?:[1-9][0-9]*|0(?:\.[0-9]+)?)$/
    loading
        13
    loading  
       297 天前
    如果是 el-input 的话,formatter parser 再结合 holder 应该就可以了,如果是前端,很好做。

    你是普通 gui 还是前端
    littlepanic72
        14
    littlepanic72  
       297 天前
    @Alias4ck 这个也有点点问题....+0010086 用这样子写的时候他还是会把 00 都认为匹配.... 不加正负号的情况 这个代码就很好了....
    littlepanic72
        15
    littlepanic72  
       297 天前
    @Alias4ck +0010086 也通不过这个测试
    Alias4ck
        16
    Alias4ck  
       297 天前
    @littlepanic72 再改下就好了 (?![+-]?0\d)[+-]?\d*\.?\d+
    Alias4ck
        17
    Alias4ck  
       297 天前   ❤️ 1
    @littlepanic72 其实不会出现你这种情况+001002 / -0023123,你发的这种数字就不太合理
    laoyutang
        18
    laoyutang  
       297 天前 via Android
    str.replace(/^0*(?!\.)/,'')
    NoOneNoBody
        19
    NoOneNoBody  
       297 天前
    你这是两个需求:校验和替换,各自正则不同,同时实施的话需要有 callback 功能的语言

    只考虑替换的话:
    ^([-+])?(0+)(([1-9][0-9\.]?)|0)$ --> $1$3
    如果全 0 带符号的情况,去掉符号的我还要想一下,这个还不行
    Pipecraft
        20
    Pipecraft  
       297 天前   ❤️ 3
    把开头连续的 0 去掉就可以。

    ```
    function removeLeadingZero(num) {
    const regex = /^([+-]?)0+(?=\d)/
    return num.replace(regex, "$1")
    }

    console.log(removeLeadingZero("00"))
    // 0
    console.log(removeLeadingZero("000"))
    // 0
    console.log(removeLeadingZero("01"))
    // 1
    console.log(removeLeadingZero("001"))
    // 1
    console.log(removeLeadingZero("0.1"))
    // 0.1
    console.log(removeLeadingZero("+0.1"))
    // +0.1
    console.log(removeLeadingZero("-0.1"))
    // -0.1
    console.log(removeLeadingZero("00.1"))
    // 0.1
    console.log(removeLeadingZero("0012340012"))
    // 12340012
    console.log(removeLeadingZero("+0010086"))
    // +10086
    console.log(removeLeadingZero("-0010086"))
    // -10086
    console.log(removeLeadingZero("+000000"))
    // +0

    ```
    bluetree2039
        21
    bluetree2039  
       297 天前
    chatpgt 对 正则很 精通~
    laoyutang
        22
    laoyutang  
       297 天前
    '00'.replace(/^0(?!\.)/,'')
    '0'
    '01'.replace(/^0(?!\.)/,'')
    '1'
    '0.1'.replace(/^0(?!\.)/,'')
    '0.1'
    zzlit
        23
    zzlit  
    OP
       297 天前
    @zhzy
    @masellum
    @GzhiYi
    @dinghmcn 感谢大佬提供另一种思路,只是这里原逻辑是用正则写的,我是进行的优化所以就顺着正则思路想了,我想想看怎么处理好
    zzlit
        24
    zzlit  
    OP
       297 天前
    @littlepanic72
    @Alias4ck
    @xiayushengfan
    @Ashore
    @Pipecraft
    @laoyutang 感谢大佬的回答,我琢磨一下正则的规则
    zzlit
        25
    zzlit  
    OP
       297 天前
    @loading 前端,是用 vue 写的指令绑在 input 上的,对输入作限制
    zzlit
        26
    zzlit  
    OP
       297 天前
    @NoOneNoBody 我本来想的也是这两个部分,拆成两个正则来走规律,但是仔细一想想好像其实用一个正则也可以满足,就是没想好...
    xiaoyai0322
        27
    xiaoyai0322  
       297 天前
    replace(/^0*/g, '').replace(/[^\d.]/g, '')
    .replace(/\.{2,}/g, '.').replace('.', '$#$')
    .replace(/\./g, '').replace('$#$', '.')
    .replace(/^\./g, '0.')
    .replace(new RegExp("^(\\-)*(\\d+)\\.(" + '\\d'.repeat(n) + ").*$"), '$1$2.$3')
    xiaoyai0322
        28
    xiaoyai0322  
       297 天前
    replace(/^0*/g, '').replace(/[^\d.]/g, '')
    .replace(/\.{2,}/g, '.').replace('.', '$#$')
    .replace(/\./g, '').replace('$#$', '.')
    .replace(/^\./g, '0.')

    最后那个是保留几位小数 //.replace(new RegExp("^(\\-)*(\\d+)\\.(" + '\\d'.repeat(n) + ").*$"), '$1$2.$3')
    magicyao
        29
    magicyao  
       297 天前
    ^([1-9][0-9]|0)*[\.]?([0-9]*[1-9])?$
    wuwukai007
        30
    wuwukai007  
       297 天前
    gpt4: /^0*(0\.|[1-9])/
    nzbin
        31
    nzbin  
       297 天前
    很久以前做过一个类似的需求。。。
    https://www.cnblogs.com/nzbin/p/6742528.html
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3342 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 11:23 · PVG 19:23 · LAX 04:23 · JFK 07:23
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.