我想找到(a)特定字符的出现,但要搜索的字符串不能在引号之间:
示例:
"this is \"my\" example string"
如果你查找char'm',那么它只应该从“example”返回'm'的索引,因为另一个'在双引号之间。
另一个例子:
"th\"i\"s \"is\" \"my\" example string"
我期待的是:
public List<Integer> getOccurrenceStartIndexesThatAreNotBetweenQuotes(String snippet,String stringToFind);
一种“天真”的方式是:
获取snippet
获取摘录中所有引号的索引
根据stringToFind的起始索引,因为你有引号的位置,你可以知道你是否在引号之间。
有更好的方法吗?
编辑:
我想要检索什么?匹配的索引。
少数事情:
要搜索的字符串中可以有很多引用的内容:“th \”我的\“是\”\“我的\”示例字符串“
在字符串中:“th”我的\“是\”\“我的\”示例字符串“,”i“,”是“和”我的“在引号之间。
不限于字母和数字,我们可以有'; :()_- = + [] {}等......
答案 0 :(得分:1)
这是一个解决方案:
<强>算法强>:
hitZones
)。hitZones
中未包含在任何deadZones
中的区域。我将把这部分留给你:)
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class FindStrings
{
// Just a simple model class for regions
static class Pair
{
int s = 0;
int e = 0;
public Pair (int s, int e)
{
this.s = s;
this.e = e;
}
public String toString ()
{
return "[" + s + ", " + e + "]";
}
}
public static void main(String[] args)
{
String search = "other";
String str = "this is \"my\" example other string. And \"my other\" this is my str in no quotes.";
Pattern p = Pattern.compile("\"([^\"]*)\"");
Matcher m = p.matcher(str);
List<Pair> deadZones = new ArrayList<Pair>();
while (m.find())
{
int s = m.start();
int e = m.end();
deadZones.add(new Pair(s, e - 1));
}
List<Pair> hitZones = new ArrayList<Pair>();
p = Pattern.compile(search);
m = p.matcher(str);
while (m.find())
{
int s = m.start();
int e = m.end();
hitZones.add(new Pair(s, e - 1));
}
System.out.println(deadZones);
System.out.println(hitZones);
}
}
注意:s
中所有Pairs
的{{1}}组件不在hitZones
范围内,最终将成为您想要的
答案 1 :(得分:0)
正如Mamun建议的那样,您可以删除引号之间的所有引号和字符串,然后搜索。以下是一个正则表达式解决方案(虽然我同意Tim的说法,它可能不适用于正则表达式引擎)。
String snippetQuoteRemoved = snippet.replaceAll("(?:\")(\\w+)(?:\")","");
// Now simply search in snippetQuoteRemoved
注意:这会查找\w+
,即([a-zA-Z0-9_]
)。将其更改为适合您的用例的任何内容。
编辑
我检查了它是否删除了所有内容,但事实并非如此。检查here。
此外,对于那些额外的特殊字符,只需将正则表达式更改为(?:")([a-zA-Z0-9_';:()_\-=+\[\]\{\}]+)(?:")
。
答案 2 :(得分:0)
另一种解决方案:
获取snippet
获取摘录中所有引号的索引
根据stringToFind的起始索引,因为你有引号的位置,你可以知道你是否在引号之间。
public List<Integer> getOccurrenceIndexesNotInQuotes(String snippet,String patternToFind) {
List<Integer> allIndexes = getStartPositions(snippet,patternToFind);
List<Integer> allQuoteIndexes = getStartPositions(snippet,"\"");
TreeSet<Integer> allQuoteIndexesTree = new TreeSet<>(allQuoteIndexes);
List<Integer> finalIndexes = new ArrayList<>();
for (Integer index : allIndexes){
Integer quoteIndexValue = allQuoteIndexesTree.floor(index);
int quoteIndex = allQuoteIndexes.indexOf(quoteIndexValue);
if (quoteIndexValue == null || !isBetweenQuote(quoteIndex)){
finalIndexes.add(index);
}
}
return finalIndexes;
}
private List<Integer> getStartPositions(String stringToProcess, String regex) {
List<Integer> out = new ArrayList<>();
Matcher matcher = Pattern.compile(regex).matcher(stringToProcess);
while(matcher.find()) {
out.add(matcher.start());
}
return out;
}
private boolean isBetweenQuote(Integer indexInQuoteList){
return indexInQuoteList % 2 != 1;
}