【发布时间】:2014-09-03 00:05:43
【问题描述】:
我有一个很大的List<String>,其中每个字符串都是一个包含 1+ 个“标记”的句子(以“a”或“b”为前缀,后跟一个正整数):
List<String> tokenList = new ArrayList<String>()
tokenList.add("How now a1 cow.")
tokenList.add("The b1 has oddly-shaped a2.")
tokenList.add("I like a2! b2, b2, b2!")
// etc.
我想编写一个函数,它接受一个 vararg 标记列表,并将返回包含 所有 标记参数的字符串的 tokenList 的子集。例如:
public class TokenMatcher {
List<String> tokenList; // Same tokenList as above
List<String> findSentencesWith(String... tokens) {
List<String> results = new ArrayList<String>();
StringBuilder sb = new StringBuilder();
// Build up the regex... (TODO: this is where I'm going wrong)
for(String t : tokens) {
sb.append(t);
sb.append("|");
}
String regex = sb.toString();
for(String sentence : tokenList) {
if(sentence.matches(regex)) {
results.add(sentence);
}
}
return results;
}
}
同样,正则表达式的构造方式必须是 all 传递给函数的tokens 必须存在于句子中,才能使匹配为真。因此:
TokenMatcher matcher = new TokenMatcher(tokenList);
List<String> results = matcher.findSentencesWith("a1"); // Returns 1 String ("How now a1 cow")
List<String> results2 = matcher.findSentencesWith("b1"); // Returns 1 String ("The b1 has oddly-shaped a2.")
List<String> results3 = matcher.findSentencesWith("a2"); // Returns the 2 Strings with a2 in them since "a2" is all we care about...
List<String> results4 = matcher.findSentencesWith("a2", "b2"); // Returns 1 String ("I like a2! b2, b2, b2!.") because we care about BOTH tokens
最后一个示例 (results4) 很重要,因为尽管“a2”标记出现在多个句子中,但 results4 我们要求该方法为包含 both 标记的句子提供匹配.这是 n-ary conjunctive,这意味着如果我们指定 50 个标记作为参数,我们只需要包含全部 50 个标记的句子。
上面的findSentencesWith 例子是我迄今为止最好的尝试。有什么想法吗?
【问题讨论】:
-
将lookaheads 组合起来以独立于匹配顺序对您有帮助吗?要匹配包含任意位置
a2和b2和c2的任何字符串,它将是:^(?=.*a2)(?=.*b2)(?=.*c2)。好吧,可能不是,你需要什么;) -
谢谢@Jonny5 (+1) - 听起来不错,但我仍然不明白这一切是如何结合在一起的(也许你可以用完整的代码示例发布答案?)。我不关心顺序或频率(也就是说,如果我可以
findSentencesWith("a2")我不在乎一个句子是否包含 1 个a2实例或 100,000 个实例)。再次感谢!