regex - 在文本中以任意顺序查找一组彼此靠近的单词
问题描述
为了突出显示多个单词的全文搜索的结果,我尝试使用正则表达式来查找具有预定义距离的项目,使用以下正则表达式(两个单词之间的距离最多 100 个字符):
word1(?:\\s|.){1,100}?word2
这会找到word1 ... word2
,但不会找到word2...word1
我知道我可以组合两个正则表达式短语,但是如果用户搜索说 6 个单词怎么办?
解决方案
我可能不会尝试使用 RegExp 来执行此操作。
如果你想在很短的距离内找到两次出现的n 个单词,那么它仍然是可行的。就像是:
var re = RegExp(r"\b(word1|...|wordn)\b[^]{1,100}\b(?:word1|...|wordn)\b(?<!\b\1)");
这应该找到 word1 到 wordn 中的任何一个,然后是 1-100 个其他字符,然后是 word1 到 wordn 中的另一个(但由于反向后视而不是同一个)。
如果您想以任何顺序查找所有单词,那么这是一个非常不规则的问题,正则表达式真的不适合。您可以将上面的表达式概括为:
RegExp(r"\b(word1|...|word10)\b"
r"[^]{1,100}\b(word1|...|word10)\b(?<!\b\1)")
r"[^]{1,100}\b(word1|...|word10)\b(?<!\b(?:\1|\2))"
...
r"[^]{1,100}\b(word1|...|word10)\b(?<!\b(?:\1|\2|\3|\4|...|\9))");
对于所有这些负面的后视,这可能不会特别有效,但最大的问题是它的字数呈二次方增长。
所以,我会做的是:
List<Match>? findWords(String source, List<String> words) {
var re = RegExp("\\b(?:${words.join("|")})\\b");
var seenWords = <String>{};
var matches = <Match>[];
for (var m in re.allMatches(source)) {
var str = m[0];
if (seenWords.add(str)) {
matches.add(m);
if (matches.length == words.length) return matches;
}
}
return null;
}
Match
这将为参数中的每个单词返回 a words
,如果它找到所有单词,如果null
没有。
推荐阅读
- scrapy - 响应查询在 shell 中工作,但在代码中给出了 SyntaxError: invalid syntax
- linux - Suse Linux 内核版本
- php - 防止 glob 选择具有特定文件名的文件
- javascript - Axios 请求 Gmail API 未授权错误?
- mysql - 您不能在 FROM 子句中指定目标表“员工”进行更新
- serialization - Kafka 消费者在发送客户对象时收到空值
- python - 用于语音识别的流式输入
- mediawiki-api - 在私人 WIKI 中使用 BOT 登录以阅读 feedrecentchanges 操作
- docker - Sonarqube 无法创建用户缓存
- angular - 在 Angular (8) 部分类名中使用变量