【问题标题】:Java - extract content inside square brackets (ignore nested square brackets)? [duplicate]Java - 提取方括号内的内容(忽略嵌套的方括号)? [复制]
【发布时间】:2019-10-04 20:01:57
【问题描述】:

我想提取方括号内的字符串内容(如果一个方括号内包含嵌套的方括号应该忽略)。

例子:

c[ts[0],99:99,99:99] + 5 - d[ts[1],99:99,99:99, ts[2]] + 5

应该返回:

 match1 = "ts[0],99:99,99:99";
 match2 = "ts[1],99:99,99:99, ts[2]";

到目前为止,我的代码仅适用于非嵌套方括号

String in = "c[ts[0],99:99,99:99] + 5 - d[ts[1],99:99,99:99, ts[2]] + 5";

Pattern p = Pattern.compile("\\[(.*?)\\]");
Matcher m = p.matcher(in);

while(m.find()) {
    System.out.println(m.group(1));
}

// print: ts[0, ts[1, 2

【问题讨论】:

  • 当有嵌套括号但在Should return 中有外部括号的嵌套括号时应该忽略?可以加一个不应该返回的例子吗?

标签: java regex algorithm parsing


【解决方案1】:

我做了一个函数来做(不是用正则表达式,但它有效)

  for (int i = 0; i < in.length(); i++){
        char c = in.charAt(i);
        String part = String.valueOf(c);
        int numberOfOpenBrackets = 0;
        if (c == '[') {
            part = "";
            numberOfOpenBrackets++;
            for (int j = i + 1; j < in.length(); j++) {
                char d = in.charAt(j);
                if (d == '[') {
                    numberOfOpenBrackets++;
                }
                if (d == ']') {
                    numberOfOpenBrackets--;
                    i = j;
                    if (numberOfOpenBrackets == 0) {
                        break;
                    }
                }
                part += d;
            }

            System.out.println(part);
            part = "[" + part + "]";
        }

        result += part;
    }

    // print: ts[0],99:99,99:99
    //        ts[1],99:99,99:99, ts[2]

【讨论】:

    【解决方案2】:

    如果嵌套只有一层,可以搜索括号之间的序列:

    • 一系列:
    • 不是[
    • [ 后跟到 ] 的最短序列

    所以

    Pattern p = Pattern.compile("\\[([^\\[]|\\[.*?\\])*\\]");
    //                             [                   ]
    //                              ( not-[ or
    //                                        [, shortest sequence to ]
    //                                               )* repeatedly
    

    问题在于括号必须正确配对:不允许出现语法错误。

    【讨论】:

      【解决方案3】:

      没有正则表达式;直接java:

      import java.util.ArrayList;
      import java.util.List;
      
      public class BracketParser {
      
          public static List<String> parse(String target) throws Exception {
              List<String> results = new ArrayList<>();
              for (int idx = 0; idx < target.length(); idx++) {
                  if (target.charAt(idx) == '[') {
                      String result = readResult(target, idx + 1);
                      if (result == null) throw new Exception();
                      results.add(result);
                      idx += result.length() + 1;
                  }
              }
              return results;
          }
      
          private static String readResult(String target, int startIdx) {
              int openBrackets = 0;
              for (int idx = startIdx; idx < target.length(); idx++) {
                  char c = target.charAt(idx);
                  if (openBrackets == 0 && c == ']')
                      return target.substring(startIdx, idx); 
                  if (c == '[') openBrackets++;
                  if (c == ']') openBrackets--;
              }
              return null;
          }
      
          public static void main(String[] args) throws Exception {
              System.out.println(parse("c[ts[0],99:99,99:99] + 5 - d[ts[1],99:99,99:99, ts[2]] + 5"));
          }
      }
      

      Complete code on GitHub

      【讨论】:

        【解决方案4】:

        您可能希望在表达式中添加右边界,然后ts 开始并在其间滑动所有内容,这可能会起作用,可能类似于this expression

        (ts.*?)(\]\s+\+)
        

        如果我们在这里有更多字符:(\s\+),您可以简单地将其与逻辑 OR 一起添加到字符列表中,它仍然可以工作。

        正则表达式

        如果这不是您想要的表达式,您可以在regex101.com 中修改/更改您的表达式。

        正则表达式电路

        您还可以在jex.im 中可视化您的表达式:

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-01-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-04-05
          • 1970-01-01
          相关资源
          最近更新 更多