正则表达式;用于捕获重复次数的特定组

时间:2012-02-29 22:48:04

标签: java regex

比较如何使用和不使用正则表达式完成下面提到的两个任务。问题:

基于SMS的食品交付的格式将是:

PABUSOG斜线或逗号重复无数次@

//数量只能是数字。为简单起见,假设数量始终为整数

e.g。 PABUSOG STRFRY_SMAI / 2 HSHBRWN_BRGR / 1 COFEEFLT / 1 @ En311

它将捕获以下内容:

STRFRY_SMAI - 2 HSHBRWN_BRGR - 1 COFEEFLT - 1

这是我的示例代码://使用正则表达式

String message = "PABUSOG ASD_ASD/1 ASD_ASA/2";

    Pattern pattern = Pattern.compile("PABUSOG(\\s+([A-Z]+_[A-Z]+)(/|,)([0-9]))+"
            ,Pattern.CASE_INSENSITIVE);

    Matcher m = pattern.matcher(message);

    try
    {
        if (m.matches())
        {

            String food = m.group(2);
            String quantity = m.group(4);

             System.out.println(food + " -- " + quantity + "\\n");


        }
    }
    catch (NullPointerException e)
    {
    }

显示ASD_ASA - 2,它会覆盖第一个ASD_ASD / 1。

必须显示

ASD_ASD - 1

ASD_ASA - 2

1 个答案:

答案 0 :(得分:2)

使用单个正则表达式为您提供组内的所有数据,您无法做到这一点。并且也不需要复杂的正则表达式。但是如果您更喜欢正则表达式,请尝试迭代搜索模式。

if (!message.startsWith("PABUSOG")) {
    return;
}

Pattern pattern = Pattern.compile("([A-Z_]+)[/,]([0-9])+", Pattern.CASE_INSENSITIVE);

Matcher m = pattern.matcher(message);
while (m.find()) {
    String food = m.group(1);
    String quantity = m.group(2);

    System.out.println(food + " -- " + quantity);
}

如果没有复杂的正则表达式,您可以使用String API执行以下操作:

// Check for correct header
if (!message.startsWith("PABUSOG")) {
    return;
}

// split by whitespaces
String[] items = message.split("\\s+");
// skip header and iterate over remaining items
for (String item : Arrays.asList(items).subList(1, items.length)) {
    // split each item by / or ,
    String[] foodQuantity = item.split("[/,]");
    assert foodQuantity.length == 2;

    String food = foodQuantity[0];
    String quantity = foodQuantity[1];

    System.out.println(food + " -- " + quantity);
}

要跳过以@开头的项目,您可以添加

if (item.startsWith("@")) {
    break; // or continue if it can be not the last
}

内部循环或以下列方式限制subList,如果您确定此类项始终存在并终止序列:Arrays.asList(items).subList(1, items.length - 1)

顺便说一句,您的模式[A-Z]+_[A-Z]+与您的示例中的COFEEFLT不匹配。