您好我想搜索并获取索引所有特殊字符,如此
这样的复杂字符串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
但即使我用
删除原始字符串,它也只能得到第一个答案 0 :(得分:2)
您可以找到所有由特殊字符分隔的文本,而不是查找每个模式匹配的开头:
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*|*|
答案 1 :(得分:2)
您的问题是,每次调用getIndexOfPat
时,您正在重新创建Matcher
实例(并且模式,但重新编译模式在这里不是问题,它只是无效的代码)。因此,每次拨打find
时,它都会尝试从头开始查找匹配项。
您可以选择如何解决此问题。
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;
}
你可以像
一样使用它String textWithSpecialChars = "text here |*more*| text some other |@tags@|...";
for (int index : getMatchedIntexes(textWithSpecialChars))
System.out.println(index);
会打印
11
17
36
42
[|]([*_@=])[^|]+\\1[|]
[|]
与代表\\|
字面值的|
相同([*_@=])
创建的第1组只能包含*
,_
,@
或=
[^|]+
会匹配一系列不是|
的字符系列(我假设您在|
内没有任何嵌套|*...*|
。如果你确实将它改为.*?
,效率可能会降低\\1
表示来自第1组的匹配,因此您只能找到|*..*|
个部分,而不是|*.._|
[|]
代表|
字面意思。