在 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 正则表达式过滤器

如何过滤 label_values(label) 的结果以获取与正则表达式匹配的标签列表?

如何在 Dart 中使用正则表达式?

c# 正则表达式 匹配中括号&颜色过滤

正则 (+Tips:查看所有关键字)

MYSQL使用正则表达式过滤数据