正则表达式 - 提取无限数量的命中

时间:2013-06-18 10:58:44

标签: java regex

方法getPolygonPoints()(见下文)成为参数的String名称,如下所示:

points={{-100,100},{-120,60},{-80,60},{-100,100},{-100,100}}

第一个数字代表x坐标,第二个数字代表y坐标。例如,第一点是

x=-100
y=100

第二点是

x=-120
y=60

等等。

现在我想提取String的点并将它们放在一个ArrayList中,最后必须看起来像这样:

[-100, 100, -120, 60, -80, 60, -100, 100, -100, 100]

这里的特殊功能是,给定字符串中的点数会发生变化,但并不总是相同。

我写了以下代码:

private ArrayList<Integer> getPolygonPoints(String name) {
    // the regular expression
    String regGroup = "[-]?[\\d]{1,3}";
    // compile the regular expression into a pattern
    Pattern regex = Pattern.compile("\\{(" + regGroup + ")");
    // the mather
    Matcher matcher;

    ArrayList<Integer> points = new ArrayList<Integer>();

    // matcher that will match the given input against the pattern
    matcher = regex.matcher(name);
    int i = 1;
    while(matcher.find()) {
        System.out.println(Integer.parseInt(matcher.group(i)));
        i++;
    }
    return points;
}

正确提取第一个x坐标,但抛出IndexOutOfBoundsException。我认为会发生这种情况,因为第2组未定义。 我想首先我必须计算点数,然后迭代这个数字。在迭代内部,我将使用简单的add()将int值放在ArrayList中。但我不知道该怎么做。也许我现在还不了解正则表达式部分。特别是小组如何运作。

请帮忙!

4 个答案:

答案 0 :(得分:4)

您似乎不了解正则表达式API的部分是捕获组编号&#34;重置&#34;每次拨打find()。或者,换句话说:捕获组的编号是它在模式中的位置,而不是输入字符串

你也是以错误的方式解决这个问题。您应该匹配您正在寻找的整个构造,在这种情况下是{x,y}对。我假设您不想验证整个字符串的格式,因此我们可以忽略外部括号和逗号:

Pattern p = Pattern.compile("\\{(-?\\d+),(-?\\d+)\\}");
Matcher m = p.matcher(name);

while (m.find()) {
    String x = m.group(1);
    String y = m.group(2);
    // parse and add to list
}

或者,由于您不关心哪个坐标是X,哪个是Y,您甚至可以这样做:

Matcher m = Pattern.compile("-?\\d+").matcher(name);
while (m.find()) {
    String xOrY = m.group();
    // parse etc.
}

现在,如果您也想验证输入,我说这是一个单独的问题,我不一定会尝试在与解析保持相同的步骤中执行此操作。正则表达式可读。 (在这种情况下可能有可能,但如果你不需要它,为什么一开始就烦恼。)

答案 1 :(得分:4)

String points = "{{-100,100},{-120,60},{-80,60},{-100,100},{-100,100}}";

String[] strs = points.replaceAll("(\\{|\\})", "").split(",");

ArrayList<Integer> list = new ArrayList<Integer>(strs.length);

for (String s : strs)
{
    list.add(Integer.valueOf(s));
}

答案 2 :(得分:0)

如何在一行中完成:

List<String> list = Arrays.asList(name.replaceAll("(^\\w+=\\{+)|(\\}+$)", "").split("\\{?,\\}?"));

您的整个方法将是:

private ArrayList<Integer> getPolygonPoints(String name) {
    return new ArrayList<String>(Arrays.asList(name.replaceAll("(^\\w+=\\{+)|(\\}+$)", "").split("\\{?,\\}?")));
}

首先剥离前导和尾随文本,然后在逗号上拆分,可选择用大括号括起来。

BTW你真的应该返回抽象类型List,而不是具体的实现ArrayList

答案 3 :(得分:0)

你也可以试试这个正则表达式:

((-?\d+)\s*,\s*(-?\d+))

它将为您提供三组:

Group 1 : x
Group 2 : y
Group 3 : x,y

您可以使用哪一个。