【问题标题】:Regex to differentiate thousand separated number vs not thousand separated number正则表达式区分千分隔数与非千分隔数
【发布时间】:2019-09-30 03:18:19
【问题描述】:

我需要在给定的文本行中提取价格信息。到目前为止,我在 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 应该匹配。问题是我当前的代码提取了123456123-456A123456中的123

【问题讨论】:

  • 使用Pattern.compile(".*\\D(\\d{1,3}(?:,\\d{3})*(?:\\.\\d+)?)") 获取最后一场比赛。返回m.group(1)
  • 或在价格后添加货币(\\d{1,3}(?:,\\d{3})*(\\.\\d+)?) USD\\b,因为您正在使用捕获组作为价格。 regex101.com/r/xTJBeX/1
  • 那么,额外的要求是至少1个逗号,对吧? Pattern.compile("\\d{1,3}(?:,\\d{3})+(?:\\.\\d+)?")?见regex101.com/r/mtLNLb/1
  • @Leni 那么如何描述 字符上下文 以获得有效匹配?你能做到吗?如果没有,没有正则表达式会帮助你。
  • 看来你可以用Pattern.compile("\\b\\d{1,3}(?:,\\d{3})*(?:\\.\\d+)?\\b")

标签: java regex text text-processing


【解决方案1】:

您的正则表达式匹配任何上下文中的数字,并且小数部分是强制性的。

我建议:

  • 仅在不包含单词字符的情况下匹配数字
  • 在分数部分模式周围使用可选的非捕获组。

使用

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

请参阅regex demo

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多