有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

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

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

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

第一个数字将被提取为序列号。 介于<>;也将被提取。然后是介于两者之间的数字序列

以下是我的模式:

"(\\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) 个答案

  1. # 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()的结果来判断是否有匹配的内容
    • 在将中间的数字列表拆分之前,< > e> EME>希望使用{{CD9}}修整尾部中可能的尾随空白。<李>
  2. # 2 楼答案

    您只需要告诉匹配器开始将模式与输入字符串匹配。这在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
    

    ^{}方法成功后,将让匹配器生成所需的信息。从javadocs:

    If the match succeeds then more information can be obtained via the start, end, and group methods.

    ^{}说了一些类似的指示,强调我的:

    Returns the input subsequence captured by the given group during the previous match operation.

  3. # 3 楼答案

    只需尝试一下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