java - Java中从非捕获组中提取捕获组

标签 java regex

我有一个字符串,我们称之为输出,它等于以下内容:

ltm data-group internal str_testclass { 
    records { 
        baz { 
            data "value 1" 
        } 
        foobar { 
            data "value 2" 
        }
        topaz {}
    } 
    type string 
}

我正在尝试提取给定“记录”名称的引号之间的子字符串。因此,给定 foobar 我想提取值 2。我想要提取的子字符串始终采用上面规定的形式,在“记录”名称之后,一个空格,一个开括号,一个换行符,空格,字符串data,然后我想要捕获的子字符串位于那里的引号之间。一个异常(exception)是没有值时,这种情况总是会发生,就像我上面用 topaz 规定的那样,在这种情况下,在“记录”名称后面只会有一个左括号和一个右括号,并且我' d 只是想为此得到一个空字符串。我怎样才能写一行Java来捕获这个?到目前为止我已经……

String myValue = output.replaceAll("(?:foobar\\s{\n\\s*data "([^\"]*)|()})","$1 $2");

但我不知道该去哪里。

最佳答案

让我们开始使用以下正则表达式提取“记录”结构 ltm\s+data-group\s+internal\s+str_testclass\s*\{\s*records\s*\{\s*(?<records>([^\s}]+\s*\{\s*(data\s*"[^"]*")?\s*\}\s*)*)\}\s*type\s*string\s*\}

然后从“记录”组,只需 find连续匹配[^\s}]+\s*\{\s*(?:data\s*"(?<data>[^"]*)")?\s*\}\s* 。 “数据”组包含您要查找的内容,在“黄 Jade ”情况下将为空。

Java 字符串:

  • "ltm\\s+data-group\\s+internal\\s+str_testclass\\s*\\{\\s*records\\s*\\{\\s*(?<records>([^\\s}]+\\s*\\{\\s*(data\\s*\"[^\"]*\")?\\s*\\}\\s*)*)\\}\\s*type\\s*string\\s*\\}"
  • "[^\\s}]+\\s*\\{\\s*(?:data\\s*\"(?<data>[^\"]*)\")?\\s*\\}\\s*"

演示:

String input = 
    "ltm data-group internal str_testclass {\n" + 
    "  records {\n" +
    "      baz {\n" + 
    "          data \"value 1\"\n" + 
    "      }\n" +
    "      foobar {\n" + 
    "          data \"value 2\"\n" + 
    "      }\n" +
    "      topaz {}\n" +
    "      empty { data \"\"}\n" +
    "    }\n" +
    "    type string\n" + 
    "}";

Pattern language = Pattern.compile("ltm\\s+data-group\\s+internal\\s+str_testclass\\s*\\{\\s*records\\s*\\{\\s*(?<records>([^\\s}]+\\s*\\{\\s*(data\\s*\"[^\"]*\")?\\s*\\}\\s*)*)\\}\\s*type\\s*string\\s*\\}");
Pattern record   = Pattern.compile("(?<name>[^\\s}]+)\\s*\\{\\s*(?:data\\s*\"(?<data>[^\"]*)\")?\\s*\\}\\s*");

Matcher lgMatcher = language.matcher(input);
if (lgMatcher.matches()) {
  String records = lgMatcher.group();
  Matcher rdMatcher = record.matcher(records);
  while (rdMatcher.find()) {
    System.out.printf("%s:%s%n", rdMatcher.group("name"), rdMatcher.group("data"));
  }
} else {
  System.err.println("Language not recognized");
}

输出:

baz:value 1
foobar:value 2
topaz:null
empty:

替代方案:在解析自定义语言时,您可以尝试编写 ANTLR 语法或创建 Groovy DSL。

关于java - Java中从非捕获组中提取捕获组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33046739/

相关文章:

java - 在没有哨兵的情况下结束 while 循环

java - 如何提取包含某个单词的每个句子

javascript - 正则表达式匹配 HTML 属性名称

Python 正则表达式 : User Inputs Multiple Search Terms

java - 为什么 Stream() 在 Scala 中不像在 Java 中那样工作?是否有其他 API 与 Stream() API 功能相同?

java - Actor 的输入监听器

javascript - JS正则表达式混淆

regex - Linux用bash脚本重命名多个文件+添加后缀

java - Android Studio 中的半空间或半空间

java - 获取对 RMI 服务器的引用时,客户端上的 RMI 生成异常