正则表达式区分千位分隔符与非千位分隔符

时间:2019-05-13 07:36:32

标签: java regex text text-processing

我需要在给定的文本行中提取价格信息。到目前为止,我在Java的正则表达式(\\d{1,3}(,\\d{3})*(\\.\\d+)?)下使用price will be 90,500 USD

但是,现在在价格开始(eg: for order number 12345 the price will be 100,500 USD)之前,我也有其他编号的行。在这种情况下,我的价格提取失败。例如,上面将给我123作为结果。

我是否可以使用正则表达式/其他方法仅提取价格信息,而不管是否存在另一个数字? (价格始终以千位分隔,带或不带小数点)

下面是我目前正在为此工作使用的完整代码:

private String getPrice(String fileText) {
    String lines[] = fileText.split(System.lineSeparator());

    for (String line : lines) {
        Pattern p = Pattern.compile("(\\d{1,3}(,\\d{3})*(\\.\\d+))");
        Matcher m = p.matcher(line);
        if (m.find()) {
            return m.group(0);
        }

        p = Pattern.compile("(\\d{1,3}(,\\d{3})*(\\.\\d+)?)");
        m = p.matcher(line);
        if (m.find()) {
            return m.group(0);
        }   
    }       
    return "";
}

我希望比赛达到单词水平。 (eg: 123 of 12345 should not match.)我的单词分隔符仅为space123-456被视为一个单词。因此,在123456123-456123,456123,456.56A123456中,只有123,456123,456.56应该匹配。问题是我当前的代码提取了123123456123-456

中的A123456

1 个答案:

答案 0 :(得分:1)

您的正则表达式在任何情况下都与数字匹配,并且小数部分是必需的。

我建议:

  • 仅当数字不包含单词字符时才匹配数字
  • 在分数部分样式周围使用可选的非捕获组。

使用

Pattern p = Pattern.compile("\\b\\d{1,3}(?:,\\d{3})*(?:\\.\\d+)?\\b");

请参见regex demo

\b模式是单词边界,(?:...)?中的(?:\\.\\d+)?是一个非捕获组,重复一次或零次,即是可选的。