使用正则表达式提取特定模式

时间:2014-05-16 21:58:01

标签: java regex

即使在线阅读了大量教程之后,我也很难在Java中使用正则表达式。我试图提取收到的String的一部分,以便稍后在我的应用程序中使用。

以下是收到的可能字符串的示例:

53248 <CERCLE> 321 211 55 </CERCLE>
57346 <RECTANGLE> 272 99 289 186 </RECTANGLE>

第一个数字将被提取为序列号。 &lt;&gt;之间的字也是要被提取出来的。然后,它们之间的数字序列也是如此。

这是我的模式:

"(\\d+)\\s*<(\\w+)>\\s*((\\d+\\s*)+)\\s*</\\w*>.*"

到目前为止,这是我方法的代码:

public decompose(String s) throws IllegalArgumentException {

    Pattern pattern = Pattern.compile(PATTERN);
    Matcher matcher = pattern.matcher(s);

    noSeq = Integer.parseInt(matcher.group(1));
    type = typesFormes.valueOf(matcher.group(2));
    strCoords = matcher.group(3).split(" ");

}

问题是,当我运行代码时,由于某种原因,我的所有匹配器组都为-1(我猜不到)。我已经在这上面敲了一会儿,欢迎提出任何建议:)谢谢。

3 个答案:

答案 0 :(得分:1)

只需尝试使用String#split()

  String str="53248 <CERCLE> 321 211 55 </CERCLE>";
  String[] array=str.split("(\\s<|>\\s)"); 
  // simple regex (space < OR > space)

注意:如果有一个或多个空格,请尝试使用\\s+

在这种情况下,使用前面三个数组值53248, CERCLE, 321 211 55


完整代码:

String str = "53248 <CERCLE> 321 211 55 </CERCLE>";
String[] array = str.split("(\\s<|>\\s)");

int noSeq = Integer.valueOf(array[0]);
String type = array[1];
String strCoords = array[2];

System.out.println(noSeq+", "+type+", "+strCoords);

输出:

53248, CERCLE, 321 211 55

答案 1 :(得分:1)

您只需要告诉匹配器开始匹配输入字符串的模式。这适用于我ideone

String s = "53248 <CERCLE> 321 211 55 </CERCLE>";
String PATTERN = "(\\d+)\\s*<(\\w+)>\\s*((\\d+\\s*)+)\\s*</\\w*>.*";
Pattern pattern = Pattern.compile(PATTERN);
Matcher matcher = pattern.matcher(s);
matcher.find();                         // aye, there's the rub
System.out.println(matcher.group(1));
System.out.println(matcher.group(2));
System.out.println(matcher.group(3));

输出是:

53248
CERCLE
321 211 55

find()方法成功后,会让匹配器产生您想要的信息。来自javadocs:

  

如果匹配成功,则可以通过start,end和group方法获得更多信息。

group()说出一些类似的指示,强调我的:

  

返回上一个匹配操作期间给定组捕获的输入子序列。

答案 2 :(得分:1)

正如@ 2rs2ts指出的那样,问题是缺少matcher.find()电话。

我会像这样进一步改进:

final String PATTERN = "(\\d+)\\s*<(\\w+)>\\s*([\\d\\s]+)\\s*</\\2>.*";
String s = "53248 <CERCLE> 321 211 55 </CERCLE>";
Pattern pattern = Pattern.compile(PATTERN);
Matcher matcher = pattern.matcher(s);
if (matcher.find()) {
    System.out.println(matcher.group(1));
    System.out.println(matcher.group(2));
    System.out.println(matcher.group(3).trim());
}

一些改进:

  • 在模式中,您可以将((\\d+\\s*)+)简化为([\\d\\s]+)。为了您的目的,它是等价的。
  • 在模式中,您可能希望将<CERCLE>与结束</CERCLE>匹配,而不是</OTHER>。您可以使用\\2执行此操作,matcher.find()是对第二个捕获组的反向引用。
  • 您可以根据.trim()的结果判断是否有任何匹配。
  • 在中间拆分数字列表之前,可能希望使用{{1}}修剪最后可能的尾随空格。