假设我想匹配一个字符串,该字符串应仅包含遵循特定(正则表达式)模式的部分,并在循环中检索元素。为此,似乎发明了Matcher.find()。但是,find将匹配任何字符串,而不仅仅是模式之后的字符串,因此将跳过中间字符。

所以-例如-我想以这样的方式匹配\\p{Xdigit}{2}(两个十六进制数字):


aabb个匹配项;
_aabb不匹配;
aa_bb不匹配;
aabb_不匹配。


通过使用find(或任何其他对regex的迭代调用),这样我就可以直接处理数组中的每个字节。所以我想在匹配后分别处理aabb

好的,就是这样,最优雅的方式赢得了接受。



笔记:


十六进制解析只是一个简单重复模式的示例;
我最好将正则表达式保持在与元素匹配所需的最低限度;
是的,我知道使用(\\p{XDigit}{2})*的知识,但是我不想扫描字符串两次(因为它应该在巨大的输入字符串上可用)。

最佳答案

您似乎想要获得所有(多个)匹配项,这些匹配项出现在字符串的开头或成功匹配之后。您可以将\G运算符与前瞻结合使用,以确保字符串仅匹配某些重复的模式。

采用

(?:\G(?!^)|^(?=(?:\p{XDigit}{2})*$))\p{XDigit}{2}


请参见regex demo

细节


(?:-以两个替代方案开始一个非捕获组:


\G(?!^)-上一次成功比赛的结束
|-或
^(?=(?:\p{XDigit}{2})*$)-字符串(^)的开头,后跟0+次出现的\p{XDigit}{2}模式直到字符串($)的结尾

)-非捕获组的结尾
\p{XDigit}{2}-2个十六进制字符。


Java demo

String regex = "(?:\\G(?!^)|^(?=(?:[0-9a-fA-F]{2})*$))[0-9a-fA-F]{2}";
String[] strings = {"aabb","_aabb","aa_bb", "aabb_"};
Pattern pattern = Pattern.compile(regex);
for (String s : strings) {
    System.out.println("Checking " + s);
    Matcher matcher = pattern.matcher(s);
    List<String> res = new ArrayList<>();
    while (matcher.find()) {
        res.add(matcher.group(0));
    }
    if (res.size() > 0) {
        System.out.println(res);
    } else {
        System.out.println("No match!");
    }
}


输出:

Checking aabb
[aa, bb]
Checking _aabb
No match!
Checking aa_bb
No match!
Checking aabb_
No match!

关于java - 查找和检索连续的比赛,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47836470/

10-13 00:20