在给定的String中查找所有String []的确切出现次数

时间:2015-12-24 11:42:56

标签: java arrays string iterator

我在数组中有一对字符串来检查另一个字符串:

String[] validPair = "{"[BOLD]", "[/BOLD]" };
String toCheck = "Example [BOLD]bold long text[/BOLD] other example [BOLD]bold short[/BOLD]";

我需要检查标签的余额,我知道如何检查字符串是否在另一个字符串中,以及如何使用字符串中的indexOfvalidPair内容并保存引用,但是是一种丑陋的方式而且我不想重新发明轮子

类似的东西:

int lastIndex = 0;
while (lastIndex != -1) {
    int index = toCheck.findNextOccurrence(validPair, lastIndex); // here use indexOf
    System.out.println(index);
    lastIndex = index;
}

我猜是否我可以检查nextOccurrence String[] validPair中任意字符串的String toCheck

一种IteratorTokenizer但不分割字符串,只提供array(或List或任何其他Object内容的出现})。

OR:

OwnIterator ownIterator = new OwnIterator<String>(toCheck, validPair);
while (toCheck.hasNext()) {
    String next = toCheck.findNextOccurrence();
    System.out.println(next);
}

输出:

[BOLD]
[/BOLD]
[BOLD]
[/BOLD]

2 个答案:

答案 0 :(得分:1)

这是我提出的解决方案。它使用正则表达式数组来搜索validPair中的每个项目,然后将所有找到的事件组合成一个列表(及其迭代器)

public class OwnIterator implements Iterator 
{
    private Iterator<Integer> occurrencesItr;

    public OwnIterator(String toCheck, String[] validPair) {
        // build regex to search for every item in validPair
        Matcher[] matchValidPair = new Matcher[validPair.length];
        for (int i = 0 ; i < validPair.length ; i++) {
            String regex = 
                    "(" +    // start capturing group
                    "\\Q" +  // quote entire input string so it is not interpreted as regex
                    validPair[i] +  // this is what we are looking for, duhh 
                    "\\E" +  // end quote
                    ")" ;    // end capturing group
            Pattern p = Pattern.compile(regex);
            matchValidPair[i] = p.matcher(toCheck);
        }
        // do the search, saving found occurrences in list
        List<Integer> occurrences = new ArrayList<>();
        for (int i = 0 ; i < matchValidPair.length ; i++) {
            while (matchValidPair[i].find()) {
                occurrences.add(matchValidPair[i].start(0)+1);  // +1 if you want index to start at 1 
            }
        }
        // sort the list 
        Collections.sort(occurrences);
        occurrencesItr = occurrences.iterator();
    }

    @Override
    public boolean hasNext()
    {
        return occurrencesItr.hasNext();
    }

    @Override
    public Object next()
    {
        return occurrencesItr.next();
    }
}

快速测试:

public static void main(String[] args)
{
    String[] validPair = {"[BOLD]", "[/BOLD]" };
    String toCheck = "Example [BOLD]bold long text[/BOLD] other example [BOLD]bold short[/BOLD]";
    OwnIterator itr = new OwnIterator(toCheck, validPair);
    while (itr.hasNext()) {
        System.out.println(itr.next());
    }
}

给出所需的输出:

9
29
51
67

编辑: 找到了一个更好的解决方案,只有一个正则表达式,其中包含validPair中带有“或”条件(|)的所有项目。那么你有Matcher自己的find()方法作为迭代器:

    String regex = "(";
    for (int i = 0 ; i < validPair.length ; i++) {
        regex += (i == 0 ? "" : "|") +  // add "or" after first item
                "\\Q" +  // quote entire input string so it is not interpreted as regex
                validPair[i] +  // this is what we are looking for, duhh 
                "\\E";  // end quote
    }
    regex += ")";
    System.out.println("using regex : " + regex);
    Pattern p = Pattern.compile(regex);
    Matcher m = p.matcher(toCheck);

    while (m.find()) {
        System.out.println(m.group(0));
    }

你得到了输出

using regex : (\Q[BOLD]\E|\Q[/BOLD]\E)
[BOLD]
[/BOLD]
[BOLD]
[/BOLD]

答案 1 :(得分:0)

你可以这样做:

int first = toCheck.indexOf(validPair[0]);
boolean ok = first > -1 && toCheck.indexOf(validPair[1], first) > 0;