实现一个类(在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个值。
理想情况下,该解决方案应支持完整的regexp语法(由Java SDK支持)。
为避免混淆,请注意,该类不应在给定字符串上迭代给定正则表达式的匹配。相反,它应该(最终)枚举符合正则表达式的所有字符串值(即匹配器的matches()方法可以接受),而不作为参数给出任何其他输入字符串。
为了进一步澄清这个问题,让我们举一个简单的例子。
RegexpIterator it = new RegexpIterator("ab?cd?e");
while (it.hasNext()) {
System.out.println(it.next());
}
此代码段应具有以下输出(行的顺序不相关,即使首先列出较短字符串的解决方案也是首选。)
ace
abce
ecde
abcde
请注意,对于某些regexp,例如ab[A-Z]*cd
,类要迭代的值集是无限的。在这些情况下,前面的代码片段会永远运行。
答案 0 :(得分: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
答案 1 :(得分: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以返回实际类型。