Java正则表达式匹配外部bracks

时间:2015-01-29 08:56:31

标签: java regex matcher

假设有一个字符串:"first option<option 1/option 2/option 3>second option<option 5/option 6/option 7>selection{aaaaa/bbbbb/ccccc}{eeeeee/fffff/ggggg}other string"

现在我想获得3 ArrayList

一个用于“&lt;&gt;”中的字符串:

{"option 1/option 2/option 3", "option 5/option 6/option 7"}

一个用于“{}”内的字符串:

{"aaaaa/bbbbb/ccccc", "eeeeee/fffff/ggggg"}

和一个外部&lt;&gt; / {}和内部&lt;&gt; / {}:

{"first option", "<option 1/option 2/option 3>", "second option", "<option 5/option 6/option 7>", "selection", "{aaaaa/bbbbb/ccccc}", "other string"}.

我知道我可以使用以下代码获取字符串:

    String Str = "first option<option 1/option 2/option 3>second option<option 5/option 6/option 7>selection{aaaaa/bbbbb/ccccc}{eeeeee/fffff/ggggg}other string"`;
    Pattern patt = Pattern.compile("<(.*?)>");
    Matcher mtchr_r = patt.matcher(Str);
    while (mtchr_r.find()){
        String ssssssss = mtchr_r.group ();
    }

但如何匹配字符串外括号?而且,如何按顺序获得第三个ArrayList?

4 个答案:

答案 0 :(得分:1)

一种选择是使正则表达式匹配所有情况,例如: (<[^>]*>)|(\{[^}]*\})|([^{<]*)(在Java中你必须逃避\ s)

但是,这不允许您区分找到的匹配类型(<...>{...}或剩余文本)。因此,根据您的问题的评论中建议使用3个正则表达式可能会更好:

Pattern pattern1 = Pattern.compile("<(.*?)>");
Pattern pattern2 = Pattern.compile("\\{(.*?)\\}");
Pattern pattern3 = Pattern.compile("(<[^>]*>)|(\\{[^}]*\\})|([^{<]*)");

然后,您只需将所有匹配项添加到列表中即可。

答案 1 :(得分:1)

我认为对于第三个,一个正则表达式不是正确的方法。我建议为三个阵列制作三种不同的模式:

String Str = "first option<option 1/option 2/option 3>second option<option 5/option 6/option 7>selection{aaaaa/bbbbb/ccccc}{eeeeee/fffff/ggggg}other string";
        Pattern inside = Pattern.compile("<(.*?)>");
        Pattern insideBrackets = Pattern.compile("\\{(.+?)\\}");
        Pattern inAndOutside = Pattern.compile("(<[^>]*>)|(\\{[^}]*\\})|([^{<]*)");
        Matcher matcher1 = inside.matcher(Str);
        Matcher matcher2 = insideBrackets.matcher(Str);
        Matcher matcher3 = inAndOutside.matcher(Str);
        ArrayList<String> array1 = new ArrayList<>();
        ArrayList<String> array2 = new ArrayList<>();
        ArrayList<String> array3 = new ArrayList<>();
        boolean found = false;
        while (matcher1.find()) {
            array1.add(matcher1.group(1));
            System.out.println(matcher1.group(1));
            found = true;
        }

        while (matcher2.find()) {
            array2.add(matcher2.group(1));
            System.out.println(matcher2.group(1));
            found = true;
        }

        while (matcher3.find()) {
            array3.add(matcher3.group(1));
            System.out.println(matcher3.group(1));
            found = true;
        }

        if (!found) {
            System.out.println("No match found");
        }
    }

答案 2 :(得分:1)

使用\G(断言下一场比赛从最后一场比赛结束的地方开始),可以一次完成:

\G(?:[^<>{}]++|<(?<pointy>[^<>]++)>|\{(?<curly>[^{}]++)\})

简单地分解上面的正则表达式:

\G                        # Must start from where last match ends
(?:
  [^<>{}]++               # Outside {} <>
  |                       # OR
  <(?<pointy>[^<>]++)>    # Capture content inside < > in group named 'pointy'
  |                       # OR
  \{(?<curly>[^{}]++)\}   # Capture content inside < > in group named 'curly'
)

假设<><>内没有{}{}内没有<>{},且没有不匹配的import java.util.ArrayList; import java.util.regex.Matcher; import java.util.regex.Pattern; public class SO28210525 { private static final Pattern re = Pattern.compile("\\G(?:[^<>{}]++|<(?<pointy>[^<>]++)>|\\{(?<curly>[^{}]++)\\})"); public static void main(String[] args) { String input = "first option<option 1/option 2/option 3>second option<option 5/option 6/option 7>selection{aaaaa/bbbbb/ccccc}{eeeeee/fffff/ggggg}other string"; Matcher matcher = re.matcher(input); ArrayList<String> tokens = new ArrayList<String>(); ArrayList<String> curly = new ArrayList<String>(); ArrayList<String> pointy = new ArrayList<String>(); int lastIndex = 0; while (matcher.find()) { tokens.add(matcher.group(0)); String inCurly = matcher.group("curly"); if (inCurly != null) { curly.add(inCurly); } String inPointy = matcher.group("pointy"); if (inPointy != null) { pointy.add(inPointy); } lastIndex = matcher.end(0); } if (lastIndex != input.length()) { System.err.println("Invalid input"); } else { System.out.println(tokens); System.out.println(curly); System.out.println(pointy); } } } ,则上面的正则表达式应该拆分正确的字符串。

正则表达式会在遇到无效序列的第一个位置停止,所以在下面的示例代码中,我确保最后一个匹配的位置在字符串的末尾。

完整示例程序(Java 7,但您可以删除指定的捕获组以使其在以前版本的Java中运行):

Matcher.start

在以前版本的Java(6及更低版本)中,您可以使用Matcher.endMatcher.start方法检查捕获组是否捕获了某些内容。

但是,在Java 7中,缺少相应的Matcher.endMatcher.group命名捕获组方法(只有{{1}}可用)。后来在Java 8中添加了这两种方法。

答案 3 :(得分:0)

(?<=<)[^>]*(?=>)|(?<={)[^}]*(?=})

您可以使用它来获取<>{}中的两个字符串。请参阅演示。

https://regex101.com/r/pM9yO9/19

使用此选项可以单独包括所有内容。

(?<=<)[^>]*(?=>)|(?<={)[^}]*(?=})|[^<>{}]+

https://regex101.com/r/pM9yO9/20