【问题标题】:Match any word of a List/Array in a Sentence java匹配句子java中列表/数组的任何单词
【发布时间】:2017-12-10 10:09:40
【问题描述】:

我有一个List 的字,如下所示

List<String> forbiddenWordList = Arrays.asList("LATE", "S/O", "SO", "W/O", "WO");

我如何理解一个String 包含List 的任何一个词。喜欢....

String name1 = "Adam Smith";      // false (not found)
String name2 = "Late H Milton";   // true  (found Late)
String name3 = "S/O Furi Kerman"; // true  (found S/O)
String name4 = "Conl Faruk";      // false (not found)
String name5 = "Furi Kerman WO";  // true  (found WO)

正则表达式高度赞赏。

【问题讨论】:

  • 我添加了一个模式解决方案,它允许保留列表选项来添加单词,并且不需要手动将单词添加到模式

标签: java regex matcher


【解决方案1】:
boolean containsForbiddenName = forbiddenWordList.stream()
     .anyMatch(forbiddenName -> name.toLowerCase()
          .contains(forbiddenName.toLowerCase()));

【讨论】:

  • 更改为方法引用名称::contains
  • 没有任何解释的回答不是很好......并且不起作用,因为 LATE 不会出现在“Late”中,而用户说它必须找到它,它必须不区分大小写跨度>
  • 和我的一样^^ 甚至我的也是一种避免代码冗余的方法
【解决方案2】:

你可以这样使用:

单词迭代 (stream) 并在任何单词(名为w)与条件(contains)匹配时返回true

public static boolean isForbidden(String word, List<String> words) {
     return words.stream().anyMatch(w -> (word.toLowerCase().contains(w.toLowerCase())));
}

使用正则表达式,它将从List构建模式本身

public static boolean isForbidden1(String word, List<String> words) {
     String forbiddenWordPattern = String.join("|", words);

     return Pattern.compile(forbiddenWordPattern, Pattern.CASE_INSENSITIVE)
                   .matcher(word)
                   .find();
 }

【讨论】:

  • (不是反对者)——你构建模式的方式非常复杂,尤其是你已经在使用Collectors.joining。无需手动添加分隔符并在之后删除第一个分隔符。 forbiddenWordPattern的整个创建都可以替换成String.join("|", words);
  • @Hulk 我不知道 String.join("|", words) 直到在上面的帖子中看到它
  • 或者,如果您出于某种原因更喜欢流,请使用Collectors.joining(CharSequence delimiter)
【解决方案3】:

列表可以表示为模式:

Pattern forbiddenWordPattern
        = Pattern.compile("LATE|S/O|SO|W/O|WO", Pattern.CASE_INSENSITIVE);

要测试文本中是否存在单词,您可以:

boolean hasForbiddenWord = forbiddenWordPattern.matcher(text).find();

【讨论】:

  • 这失去了使用列表的所有好处,如果用户想轻松添加数千个禁用词,他不想全部添加到模式中
  • @azro 是的,但问题以“正则表达式高度赞赏”结尾。
  • 是的,这不是一个简单的解决方案,请看下面我添加了一个允许自动构建模式的解决方案
  • 对于String name = "Jhon Solomon"; 返回true。但我期待false 在这里,因为那里没有“SO”这个词。
【解决方案4】:
  1. 使用 | 将列表转换为字符串分隔符

    String listDelimited = String.join("|",forbiddenWordList)

  2. 创建正则表达式

    模式禁止WordPattern = Pattern.compile(listDelimited , Pattern.CASE_INSENSITIVE);

  3. 测试你的文字

    boolean hasForbiddenWord=forbiddenWordPattern.matcher(text).find();

(类似于@Maurice Perry 的回答)

【讨论】:

  • 对于String name = "Jhon Solomon"; 返回true。但我期待false 在这里,因为那里没有“SO”这个词。
【解决方案5】:

在大家的帮助下,我自己终于找到了解决方案....

    String regex = String.join("|", forbiddenWordList.stream().map(word -> "\\b" + word + "\\b").collect(Collectors.toList()));
    Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
    System.out.println(pattern.matcher(name).find());

单词边界 (\\b) 有助于找到准确的单词,而不是匹配的文本。 感谢大家的帮助。

【讨论】:

    猜你喜欢
    • 2022-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-14
    • 2010-12-29
    • 2020-02-11
    相关资源
    最近更新 更多