0

什么是实现一个类(在 Java 中)的最简单方法,该类将用作符合给定正则表达式的所有值集的迭代器?

假设我有这样的课程:

public class RegexpIterator
{
  private String regexp;

  public RegexpIterator(String regexp) {
    this.regexp = regexp;
  }

  public abstract boolean hasNext() {
    ...
  }

  public abstract String next() {
    ...
  }
}

我该如何实施?该类假定对所有符合值的集合进行一些线性排序,并且 next() 方法应在第 i 次调用时返回第 i 个值。

理想情况下,解决方案应该支持完整的正则表达式语法(Java SDK 支持)。


为避免混淆,请注意该类不应该在给定字符串上迭代给定正则表达式的匹配项。相反,它应该(最终)枚举所有符合正则表达式的字符串值(即会被匹配器的matches() 方法接受),而不需要任何其他输入字符串作为参数。


为了进一步澄清这个问题,让我们举一个简单的例子。

RegexpIterator it = new RegexpIterator("ab?cd?e");
while (it.hasNext()) {
  System.out.println(it.next());
}

此代码片段应具有以下输出(行的顺序无关紧要,即使首选列出较短字符串的解决方案)。

ace
abce
ecde
abcde

请注意,对于某些正则表达式,例如ab[A-Z]*cd,类要迭代的值集是无限的。在这些情况下,前面的代码片段将永远运行。

4

2 回答 2

3

你需要实现一个类吗?这种模式效果很好:

    Pattern p = Pattern.compile("[0-9]+");
    Matcher m = p.matcher("123, sdfr 123kjkh 543lkj ioj345ljoij123oij");
    while (m.find()) {
        System.out.println(m.group());
    }

输出:

123
123
543
345
123

对于更通用的解决方案:

public static List<String> getMatches(String input, String regex) {
    List<String> retval = new ArrayList<String>();
    Pattern p = Pattern.compile(regex);
    Matcher m = p.matcher(input);
    while (m.find()) {
        retval.add(m.group());
    }
    return retval;
}

然后可以这样使用:

public static void main(String[] args) {
    List<String> matches = getMatches("this matches _all words that _start _with an _underscore", "_[a-z]*");
    for (String s : matches) { // List implements the 'iterable' interface
        System.out.println(s);
    }
}

产生这个:

_all
_start
_with
_underscore

可以在此处找到有关 Matcher 类的更多信息:http: //docs.oracle.com/javase/6/docs/api/java/util/regex/Matcher.html

于 2013-07-03T16:29:04.313 回答
0

这是另一个工作示例。这可能会有所帮助:

public class RegxIterator<E> implements RegexpIterator {

private Iterator<E> itr = null;

public RegxIterator(Iterator<E> itr, String regex) {
    ArrayList<E> list = new ArrayList<E>();
    while (itr.hasNext()) {
        E e = itr.next();
        if (Pattern.matches(regex, e.toString()))
            list.add(e);
    }
    this.itr = list.iterator();
}

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

@Override
public String next() {
    return this.itr.next().toString();
}

}

如果要将其用于其他数据类型(Integer、Float等或toString()有意义的其他类),请声明next()以返回Object而不是String。然后您可以对返回值执行 typeCast 以取回实际类型。

于 2013-07-03T18:09:17.790 回答