Regex无法匹配带有外来符号的单词

问题描述 投票:1回答:1

我有以下方法检查用户使用的术语是否被列入黑名单。

  static checkAgainstBlacklist(blacklistTerms, term) {
    return blacklistTerms.some(word =>
      (new RegExp(`\\b${word}\\b`, 'i')).test(term)
    );
  }

奇怪的是,它对带有特殊字符的单词失败:

  it('should return true if sentence contains blacklisted term',
    inject([BlacklistService], () => {
      const blacklistTerms = [
        'scat',
        'spic',
        'forbanna',
        'olla',
        'satan',
        'götverenlerden',
        '你它马的',
        '幼児性愛者',
      ];
      expect(BlacklistService.checkAgainstBlacklist(blacklistTerms, 'scat')).toEqual(true);
      expect(BlacklistService.checkAgainstBlacklist(blacklistTerms, 'scat-website')).toEqual(true);
      expect(BlacklistService.checkAgainstBlacklist(blacklistTerms, 'spic')).toEqual(true);
      expect(BlacklistService.checkAgainstBlacklist(blacklistTerms, 'website-spic')).toEqual(true);
      expect(BlacklistService.checkAgainstBlacklist(blacklistTerms, 'forbanna')).toEqual(true);
      expect(BlacklistService.checkAgainstBlacklist(blacklistTerms, 'olla')).toEqual(true);
      expect(BlacklistService.checkAgainstBlacklist(blacklistTerms, 'satan-website')).toEqual(true);
      expect(BlacklistService.checkAgainstBlacklist(blacklistTerms, 'götverenlerden')).toEqual(true);
      expect(BlacklistService.checkAgainstBlacklist(blacklistTerms, '你它马的')).toEqual(true);
      expect(BlacklistService.checkAgainstBlacklist(blacklistTerms, '幼児性愛者')).toEqual(true);
    })
  );

所有测试均通过这三个测试:

      expect(BlacklistService.checkAgainstBlacklist(blacklistTerms, 'götverenlerden')).toEqual(true);
      expect(BlacklistService.checkAgainstBlacklist(blacklistTerms, '你它马的')).toEqual(true);
      expect(BlacklistService.checkAgainstBlacklist(blacklistTerms, '幼児性愛者')).toEqual(true);

我该如何修正我的regex命令,使其能够识别这些术语?

typescript karma-jasmine
1个回答
1
投票

[\b匹配单词边界,但是失败的字符串中的第一个和最后一个字符(n中的最后一个götverenlerden除外)不是单词字符,因此该模式不匹配。

您可以通过匹配字符串的开头/结尾或某些分隔符(如空格和标点符号来更改它:

static checkAgainstBlacklist(blacklistTerms, term) {
  return blacklistTerms.some(word =>
    (new RegExp(
      String.raw`(?:^|(?!\w)[\u0000-\u007f])${word}(?:$|(?!\w)[\u0000-\u007f])`,
      'im'
    )).test(term)
  );
}

您可以看到正在使用的字符代码here。本质上,(?!\w)[\u0000-\u007f]的作用是将字符代码0到字符代码255中的任何字符匹配,该字符<< [not不在0-9或A-Z或a-z或_的范围内。

它会产生类似的图案:

(?:^|(?!\w)[\u0000-\u007f])götverenlerden(?:$|(?!\w)[\u0000-\u007f])

https://regex101.com/r/AHRVgA/1

[另一种方法是用分隔符(如标点符号,空格等-如上面的模式中的内容)分隔输入字符串,然后检查结果字符串中是否有任何单词包含在blacklistTerms中。

也就是说,无论您使用自动过滤器的逻辑是什么,用户通常都足够有创造力,以找出在不触发过滤器的情况下传达消息的方法。

© www.soinside.com 2019 - 2024. All rights reserved.