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

3

我需要从给定的文本行中提取价格信息。到目前为止,我已经用以下java正则表达式(\\d{1,3}(,\\d{3})*(\\.\\d+)?)成功地处理了像price will be 90,500 USD这样的行。

但现在,我也有一些行在价格之前还有另一个数字(例如:对于订单号码12345,价格将为100,500美元)。在这种情况下,我的价格提取失败了。例如,上面的例子会给我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 "";
}

我期望匹配的是单词级别。例如:12345中的123不应该匹配。我的单词分隔符只有空格。123-456被视为一个单词。因此,在123456、123-456、123,456、123,456.56和A123456中,只有123,456和123,456.56应该匹配。问题是,我的当前代码从123456、123-456和A123456中提取了123。

1
使用 Pattern.compile(".*\\D(\\d{1,3}(?:,\\d{3})*(?:\\.\\d+)?)") 获取最后一个匹配。返回 m.group(1) - Wiktor Stribiżew
1
或者在价格后面添加货币符号 (\\d{1,3}(?:,\\d{3})*(\\.\\d+)?) USD\\b,因为你正在使用一个捕获组来匹配价格。https://regex101.com/r/xTJBeX/1 - The fourth bird
1
所以,额外的要求是至少有一个逗号,对吗? Pattern.compile("\\d{1,3}(?:,\\d{3})+(?:\\.\\d+)?")?请参见 https://regex101.com/r/mtLNLb/1 - Wiktor Stribiżew
1
@Leni 那么你如何描述一个有效匹配的字符上下文呢?你能做到吗?如果不能,那么正则表达式也无法帮助你。 - Wiktor Stribiżew
1
看起来你可能会使用 Pattern.compile("\\b\\d{1,3}(?:,\\d{3})*(?:\\.\\d+)?\\b") - Wiktor Stribiżew
显示剩余8条评论
1个回答

1
您的正则表达式可以匹配任何上下文中的数字,小数部分是必须的。
我建议:
  • 仅在数字不被单词字符包围时匹配
  • 在分数部分模式周围使用一个可选的非捕获组。
使用:
Pattern p = Pattern.compile("\\b\\d{1,3}(?:,\\d{3})*(?:\\.\\d+)?\\b");

请查看正则表达式演示

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接