两种可能模式的复合正则表达式

时间:2016-03-26 23:42:20

标签: java regex

我试图在java中进行一些正则表达式模式匹配,以尝试从具有两种不同模式的结构文件中导入值。

我的文件可能如下所示:

[Group Variable]
name = Value

[Valid Extensions]
images = {
jpeg
png
}

此文件是java程序的配置文件。我在这里使用了java代码的修改版本:What is the easiest way to parse an INI file in Java?

此代码允许我对名称等变量名称进行特定请求。 (因此无需在等号左侧保存任何内容。

第一种模式很简单,“在等号后面的线上抓取任何内容”。正则表达式非常简单:(\s*([^=]*)=(.*))

第二个稍微复杂一点“在花括号之间的等号后抓住所有内容(即包围分散在多行中的数组元素)”

我试图使用(?<=\\{)(.*?)(?=\\})

的修改在两个花括号之间找到文本

我尝试设置if语句来忽略包含([^\{]|^)* https://stackoverflow.com/a/1264575/4383447等开放大括号的行。从我的阅读正则表达式支持如果那么逻辑(?(?=regex)then|else)所以

我无法获得这个或两个组合工作的regix。并且我最好使用一个复杂的正则表达式来处理这两种情况,而不是在java端使用迭代或递归。

有趣的是,我的一些尝试似乎在java方面失败了,而其他人虽然可能已经工作但似乎没有按照https://regex101.com/r/aG1xO0/2进行测试。当我决定将其作为一个问题发布时,我仍记录的一些尝试如下。我不再在if和or逻辑替代方面做出努力。

(\s*([^=]*)=\{)(.*?)(?=\})
(\s*([^=]*)=(?<=\{)(.*?)(?=\}))
\s*([^=]*)=(?(?=([^{]|^)(.*))(.*)|{([^}]*)})
\s*([^=]*)=(.*))|(\s*([^={*}]*)=\{)(.*?)(?=\})

3 个答案:

答案 0 :(得分:1)

根据您的描述,您可能正在寻找类似

的内容
Pattern p = Pattern.compile("=\\s*(\\{[^}]*\\}|.*)");
Matcher m = p.matcher(data);
while(m.find()){
    System.out.println(m.group(1));
    System.out.println("------");
}

DEMO

解释。

我们正在寻找=之后存在的一些部分以及可选的空格。但我们不需要那部分,所以我们可以

  1. 使用look-behind (?<=...)
    1. 在捕获组中包装所需的部分。
    2. 选项1在这里是不可能的,因为后视必须具有明显的最大长度\s*(零个或多个可选空格)阻止。这意味着我们留下了选项2.
      现在需要描述我们感兴趣的两个案例。为此,我们将使用case1|case2,我们将把它放在捕获组中。为了避免匹配case1将阻止匹配case2的情况,我们需要在开始时编写大多数特定情况。这是表示区域{.\n.\n.}的正则表达式,因为正则表达式仅匹配一行{.可能会阻止我们匹配\n.\n.}部分的其余部分。

      现在{...}可以表示为\\{[^}](\\}[^}]表示任何non-}字符,这意味着我们也可以匹配行分隔符。因此它优于.*?,因为我们不需要费心使正则表达式看到.所有字符包括带有Pattern.DOTALL标记的行分隔符。我们也不需要使用不情愿的量词*?,因为回溯会降低性能。

      避免Pattern.DOTALL也有这个优势,我们可以将代表第二种情况的正则表达式(=之后的其余部分)简单地写为.*,因为.将无法匹配行分隔符。

      如果您还想包含属性名称,可以使用带有MULTILINE标志的^([^=\n\r]+?)\s*=\s*(\{([^}]*)\}|.*)正则表达式(允许^表示每行的开头,而不仅仅是整个文本的开头)。

      DEMO 2

答案 1 :(得分:0)

\{([\w\n]*)\}

这从结构中提取jpeg和png。

答案 2 :(得分:0)

由于并非所有行都包含花括号,我建议使用两个步骤来分割String(这样如果找不到花括号匹配,您仍然可以继续处理原始String

第1步是使用正则表达式提取Strings,一旦我们得到String,我们就可以使用以下内容来提取花括号之间的内容:

String string = "fdwfs{aaaa}fsfds";
Pattern pattern = Pattern.compile("\\{(.*?)\\}");
Matcher matcher = pattern.matcher(string);
while (matcher.find()) {
    System.out.println(matcher.group(1));
}

如果找不到匹配,则不会进入while。在这种情况下,我们可以处理整个String