在 dart 中使用动态全词匹配正则表达式过滤列表
Posted
技术标签:
【中文标题】在 dart 中使用动态全词匹配正则表达式过滤列表【英文标题】:Filter list using dynamic whole word matching regex in dart 【发布时间】:2020-08-01 00:02:39 【问题描述】:我正在过滤这样的列表,但我认为应该有更好的方法来过滤列表,其中 bloc 不允许我声明变量。有没有其他方法可以达到同样的效果
var cc = contactsAll
.where(
(i) =>
regularExpression(i.displayName, 'dev') ||
regularExpression(i.displayName, 'soft') ||
regularExpression(i.displayName, 'angular') ||
regularExpression(i.displayName, 'java')
)
.toList();
我的表情过滤函数
bool regularExpression(String stringg, String search)
RegExp exp = new RegExp(
"\\b" + search + "\\b",
caseSensitive: false,
);
return exp.hasMatch(stringg);
提前致谢
【问题讨论】:
【参考方案1】:您可以动态构建模式:
var keys = ['dev', 'soft', 'angular', 'java'];
var regex = new RegExp("\\b(?:$keys.join('|'))\\b", caseSensitive: false);
var contactsAll = ['No match', 'I like java', 'I like javascript'];
var cc = contactsAll.where( (i) => regex.hasMatch(i) ).toList();
print(cc); // => [I like java]
正则表达式看起来像\b(?:dev|soft|angular|java)\b
,并且由于\b
word boundaries 将匹配non-capturing group 中的任何关键字作为一个完整的单词。请参阅regex demo。
如果keys
可以包含特殊字符,但您仍需要进行全词搜索,则需要转义所有特殊字符并使用明确的边界
var regex = new RegExp("(?:^|\\W)(?:$keys.map((val) => val.replaceAll(new RegExp(r'[-\/\\^$*+?.()|[\]]'), r'\\$&')).join('|'))(?!\\w)", caseSensitive: false);
这会导致(?:^|\W)(?:dev|soft|angular|java)(?!\w)
模式(see demo),其中(?:^|\W)
匹配字符串开头或非单词字符,(?!\w)
要求在当前位置右侧没有单词字符。
.map((val) => val.replaceAll(new RegExp(r'[-\/\\^$*+?.()|[\]]'), r'\\$&'))
部分 escapes the literal part for use within regex。
或空白边界:
var regex = new RegExp("(?:^|\\s)(?:$keys.map((val) => val.replaceAll(new RegExp(r'[-\/\\^$*+?.()|[\]]'), r'\\$&')).join('|'))(?!\\S)", caseSensitive: false);
这会产生(?:^|\s)(?:dev|soft|angular|java)(?!\S)
模式,其中(?:^|\s)
匹配字符串开头或空白字符,(?!\S)
要求在当前位置右侧不存在非空白字符。
请参阅regex demo。
【讨论】:
嗨@Wiktor Stribiżew,您的解决方案正在按照我的问题工作。但它不适用于对象列表` var cc = contactsAll.where((i) => regex.hasMatch(i.displayName)).toList(); ` 你能帮帮我吗 @arjunmore 它应该可以工作。请提供可重现的样本来重现问题。你如何初始化contactsAll
对象?
我很抱歉我两次错误地列出了列表。按预期工作非常感谢【参考方案2】:
无需创建函数,您可以像这样在 displayName 上使用 contains
方法:
var cc = contactsAll
.where((i) =>
i.displayName.contains(RegExp('\\bdev\\b')) ||
i.displayName.contains(RegExp('\\bsoft\\b')) ||
i.displayName.contains(RegExp('\\bangular\\b')) ||
i.displayName.contains(RegExp('\\bjava\\b')),)
.toList();
【讨论】:
谢谢@F Perroch以上是关于在 dart 中使用动态全词匹配正则表达式过滤列表的主要内容,如果未能解决你的问题,请参考以下文章
ansible Regular Expression Filters 正则表达式过滤器