RegEx:匹配重复字符的n-char长序列

时间:2016-01-14 07:37:37

标签: java regex

我想拆分一个可能如下所示的文本字符串:

(((Hello! - > (((Hello!

########No? - > ########No?

一开始我有n次相同的特殊字符,但我希望匹配最长的序列。

我现在拥有的是这个正则表达式: ([^a-zA-Z0-9])\\1+([a-zA-Z].*)

这个将返回第一个例子 ((仅限1次)和Hello!

和第二个 #No!

如何告诉regEx我想要匹配字符的最大长重复次数?

我正在使用RegEx作为Java程序的一部分,以防万一。

1 个答案:

答案 0 :(得分:1)

我建议使用2个正则表达式的以下解决方案:(?s)(\\W)\\1+\\w.*用于检查字符串在开头是否包含相同的重复非单词符号,如果是,则仅使用(?<=\\W)(?=\\w)模式进行拆分(非{ -word和一个单词字符),否则,只返回一个包含整个字符串的列表(好像没有拆分):

String ptrn = "(?<=\\W)(?=\\w)";
List<String> strs = Arrays.asList("(((Hello!", "########No?", "$%^&^Hello!");
for (String str : strs) {
    if (str.matches("(?s)(\\W)\\1+\\w.*")) {
        System.out.println(Arrays.toString(str.split(ptrn)));
    }else { System.out.println(Arrays.asList(str)); }
}

请参阅IDEONE demo

结果:

[(((, Hello!]
[########, No?]
[$%^&^Hello!]

此外,您的原始正则表达式可以修改为符合以下要求:

String ptrn = "(?s)((\\W)\\2+)(\\w.*)";
List<String> strs = Arrays.asList("(((Hello!", "########No?", "$%^&^Hello!");
for (String str : strs) {
    Pattern p = Pattern.compile(ptrn);
    Matcher m = p.matcher(str);
    if (m.matches()) {
        System.out.println(Arrays.asList(m.group(1), m.group(3)));
    }
    else { 
        System.out.println(Arrays.asList(str)); 
    }
}

请参阅another IDEONE demo

正则表达式匹配:

  • (?s) - DOTALL内联修饰符(如果字符串有换行符,.*也会匹配它们。)
  • ((\\W)\\2+) - 捕获组1匹配并捕获到组2中的非单词字符后跟相同的字符(因为使用了反向引用\2)1个或多个次。
  • (\\w.*) - 匹配并捕获第3组中的单词字符,然后填充一个或多个字符。