【问题标题】:Match numbers in different formats匹配不同格式的数字
【发布时间】:2017-11-02 05:35:50
【问题描述】:
  • 我有一个用英文写的匹配号码的正则表达式:
    [1-9]\d{0,2}(,\d{1,3})+(\.\d+)?
    例如,buy a sport car 1,000,000.25 将匹配此正则表达式。
  • 我还有一个用我的语言编写的匹配数字的正则表达式(越南语 - 基本上 ,. 符号被交换)
    [1-9]\d{0,2}(\.\d{1,3})+(,\d+)?
    例如,buy a sport car 1.000.000,25 将匹配此正则表达式。
    这就是我要的:
    1. 如果一个数字与英文数字正则表达式匹配,它不应与越南数字正则表达式匹配。但是,在像这样的复杂情况下:buy a house 1.234.532.727,94 in October 它匹配两个正则表达式。
    2. 鉴于 英文正则表达式 的情况,我当前的英文正则表达式无法匹配此字符串:2.45 buy a song
    3. 从这个字符串:buy a house 1.234.532.727,94 in October,我怎样才能提取这个字符串:1.234.532.727,94

我应该如何纠正我的正则表达式以获得我想要的?

【问题讨论】:

    标签: javascript regex numbers separator


    【解决方案1】:

    对于您问题的第二部分,要使英语语言环境正则表达式匹配 2.45,您需要做的就是将逗号术语 (,\d{1,3}) 设为可选:

    [1-9]\d{0,2}(,\d{1,3})*(\.\d+)?
                         ^^^ change + to *
    

    对于您的第一个问题,我认为您单独的正则表达式已经正确过滤掉了英语或越南语区域设置,q.v。下面的两个演示。我唯一需要做的就是添加锚点^$

    English

    Vietnamese

    更新:

    如果你想从下面的句子中提取英文区域编号:

    buy books 12.45 at school
    

    那么你可以试试这个代码:

    var regex = /.*(?:\s+|^)([1-9]\d{0,2}(?:,\d{1,3})*(?:\.\d+)?)(?:\s+|$).*/g;
    var matches = regex.exec("buy books 12.45 at school");
    console.log(matches[1]);
    

    Demo

    【讨论】:

    • 谢谢!我刚刚更新了我的问题。如果我想匹配这句话:buy a sport car 1,000,000.25 in English 怎么办?另外,我怎样才能从上面的句子中提取这个字符串1,000,000.25
    • 您要匹配确切的文本还是一般的任何文本?
    • 一般任何文字,例如buy books 12.45 at school,我想从句子中提取12.45
    • @sonlexqt 我进行了更新以解决您的新问题。
    【解决方案2】:

    如果一个数字匹配英文数字正则表达式,它不应该匹配 越南数字正则表达式

    两个正则表达式都使用 start ^ 和 end $,所以

    /^[1-9]\d{0,2}(,\d{1,3})+(\.\d+)?$/.test( "1.234.532.727,94" ) ; //false 
    

    鉴于英语正则表达式的情况,我当前的英语正则表达式不能 匹配这个字符串:2.45

    这是因为(,\d{1,3})+ 至少需要出现一个 3 位数字,所以将其设为 (,\d{1,3})*

    /^[1-9]\d{0,2}(,\d{1,3})*(\.\d+)?$/.test( "2.45" ); //true
    

    编辑

    正如@RobG 在下面指出的那样,如果您想处理0,000.1230.123 之类的场景,请将初始[1-9]\d{0,2} 替换为\d{1,3}

    举例

    /^\d{1,3}(,\d{1,3})*(\.\d+)?$/.test( "0,000.123" ); //true
    
    /^\d{1,3}(,\d{1,3})*(\.\d+)?$/.test( "0.123" );  //true
    

    编辑 2

    如果这必须是字符串的一部分,则在正则表达式周围放置一个单词边界,而不是开始和结束符号。

    /\b\d{1,3}(,\d{1,3})*(\.\d+)?\b/.test( "asd 0,000.123 sad" ); //true
    

    ^$ 替换为 \b

    编辑 3

    使用这种方法

    var input = "buy a house 1.234.532.727,94";
    
    var matches = input.split(" ").filter( function( item ) { return item.match( /(\d{1,3}(,\d{1,3})*(\.\d+)?)/g ) });
    
    console.log( matches );

    【讨论】:

    • ^[1-9]\d{0,2} 应该是 ^\d{1,3} 否则像 0.123 这样的数字会因为前导零而失败。另外,0,000.123 是什么意思?
    • @gurvinder372 谢谢!我刚刚更新了我的问题。如果我想匹配这句话:buy a sport car 1,000,000.25 in English 怎么办?另外,我怎样才能从上面的句子中提取这个字符串1,000,000.25
    • @gurvinder372 谢谢!关于如何提取数字字符串的任何建议?比如buy a house 1.234.532.727,94,我要获取数字字符串1.234.532.727,94
    【解决方案3】:

    为此目的的最佳正则表达式将是

    (?:^|\s)(\d{1,3}(?:,\d{3})*(?:\.\d+)?)(?!\S)
    

    请参阅regex demo

    (?:^|\s) 匹配数字之前的字符串开头或空格,(?!\S) 检查数字之后的空格或字符串结尾,而不使用它们。

    JS 演示:

    var rx = /(?:^|\s)(\d{1,3}(?:,\d{3})*(?:\.\d+)?)(?!\S)/g;
    var str = "buy a sport car 1,000,000.25 1.000.000,25 2,000,000.25 3,000,000.25 test 2.45 and reject test 2,45";
    var res=[], m;
    
    while (m = rx.exec(str)) {
        res.push(m[1]);
    }
    console.log(res);

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-28
    • 2013-01-14
    • 1970-01-01
    • 2018-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多