Java 带特殊字符的模式搜索

Java 带特殊字符的模式搜索,java,regex,pattern-matching,Java,Regex,Pattern Matching,嗨,我想搜索并获取索引,在一个复杂字符串中的所有特殊字符,如下所示 String textWithSpecialChars = "text here |*more*| text some other |@tags@|..."; 我正在尝试搜索像这样的所有模式|*| | |=|@和*| |=|@我尝试了这种模式 public int getIndexOfPat(String s){ Pattern startPat = Pattern.compile("\\|[\\*_@=]");

嗨,我想搜索并获取索引,在一个复杂字符串中的所有特殊字符,如下所示

String textWithSpecialChars = "text here |*more*| text some other |@tags@|...";
我正在尝试搜索像这样的所有模式|*| | |=|@和*| |=|@我尝试了这种模式

public int getIndexOfPat(String s){
    Pattern startPat = Pattern.compile("\\|[\\*_@=]");
    Matcher matcher = pattern.matcher(s);
    return matcher.find() ? matcher.start() : -1;
}

String textWithSpecialChars = "text here |*more*| text some other |@tags@|...";
int i = getIndexOfPat(textWithSpecialChars);
textWithSpecialChars = textWithSpecialChars.substring(i+2);
//I get error here
i = getIndexOfPat(textWithSpecialChars);
// var i still is the first one value

但这只会得到第一个,即使我用

从原始字符串中删除它,而不是查找每个模式匹配的开头,您可以找到所有由特殊字符分隔的文本,如:

public List<String> getSpecialTextList(String line) {
    List<String> toRet = new ArrayList<String>();

    Pattern pattern = Pattern.compile("\\|([\\*_@=])((?:.(?!\\|))*)\\1\\|");
    Matcher matcher = pattern.matcher(line);
    while (matcher.find()) {
      toRet.add(matcher.group(2));
    }

    return toRet;
}
然后您可以这样使用它:

String textWithSpecialChars = "text here |*more*| text some other |@tags@|...";
List<String> specialTextList = getSpecialTextList(textWithSpecialChars);
System.out.println(specialTextList); // prints [more, tags]

请注意,这不适用于嵌套标记,如|*hello |*there*|*|

您的问题是,每次调用getIndexOfPat时,您都在重新创建Matcher实例和模式,但在这里重新编译模式不是问题,它只是无效的代码。因此,每次调用find时,它都会从一开始就尝试查找匹配项

你几乎没有办法解决这个问题

let方法返回所有已建立匹配项的列表 传递Matcher的方法实例,这样您就可以调用Matcher上的find,它会记住上次匹配的位置并搜索它。 我会选择选项1,因为选项2只是包装find方法并返回其结果,这感觉太简单了,不像单独的方法那样

int getNextIndex(Matcher m){
    return matcher.find() ? matcher.start() : -1;
}
选项1可能看起来像

static Pattern pattern = Pattern.compile("[|]([*_@=])[^|]+\\1[|]");

public static List<Integer> getMatchedIntexes(String s) {
    List<Integer> result = new ArrayList<>();
    Matcher m = pattern.matcher(s);
    while (m.find()){
        result.add(m.start()+1);//index of character after `|`
        result.add(m.end()-1);  //index of character before `|`
    }

    return result;
}
哪个会打印

11
17
36
42
解释[|][*.@=][^[124;]+\\ 1[|]

[|]与\\|相同,表示|文字 [*.@=]创建组1,该组只能包含*、或= [^ |]+将匹配至少一个字符的序列,该字符不是|我假设您没有任何嵌套的|内|*…*|。如果您将其更改为。*?这可能会降低效率 \\1表示组1中的匹配项,因此您只能找到|*..*|节,而不能找到|*_| 如前所述,[|]表示|文字。
搜索的部分是否可以包含内部的| like |*foo | bar*|?
11
17
36
42