【问题标题】:Find secuentially occurrences of all String[] in a given String查找给定 String 中所有 String[] 的连续出现
【发布时间】:2016-03-30 20:50:26
【问题描述】:

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

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;
}

我在猜测是否有办法可以检查String[] validPairString[] validPair 中的任何字符串的nextOccurrence String toCheck

一种IteratorTokenizer,但不拆分字符串并仅给出array(或List 或任何其他Object)内容的出现次数。

或者:

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

输出:

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

【问题讨论】:

  • 整个事情的期望输出是什么?只是是/否标签是否平衡或索引元组,或者。 ..?到目前为止,您究竟尝试了什么来获得该输出?
  • validPair 中任何出现的下一个索引我将更新
  • @luk2302 请检查我的更新
  • 您可能想研究正则表达式,构建一个表示打开标签、内容和结束标签的集合。不过,如果标签不能嵌套,那会容易得多。

标签: java arrays string iterator


【解决方案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]

【讨论】:

  • 伟大的@sharon,只是,你没有注意到最后的修改......有一种方法可以获取标签的名称而不是位置??对不起最后一分钟的改变......:$
  • 也许您可以自己实现?你只需要替换 Matcher 方法(而不是 start(group-number) 到别的东西)。真的是一个很小的改变,你将获得一些(需要的)Java regex 经验
  • 找到了一个更好的解决方案,它使用一个 reg 表达式。查看编辑后的答案
【解决方案2】:

你可以这样做:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-20
    • 1970-01-01
    • 2018-10-20
    相关资源
    最近更新 更多