【问题标题】:Search multiple words in a text using regular expressions (Java)使用正则表达式搜索文本中的多个单词 (Java)
【发布时间】:2019-11-16 02:32:29
【问题描述】:

我有一种在文本中搜索单词的方法,两者都通过参数插入。

public Integer findTheWord(String stringToCheck, String regexString) throws IOException {

        int count = 0;
        Pattern regexp = Pattern.compile("\\b" + regexString + "\\b");
        Matcher matcher = regexp.matcher(stringToCheck);

        while (matcher.find()) {
                count++;
                String matchString = matcher.group();
                System.out.println(matchString);
            }
        System.out.println(count);
        return count;
  }

如何插入多个单词并返回每个单词的出现次数?

【问题讨论】:

  • 来自docs - 逻辑运算符X|Y Either X or Y。在你的情况下 - [word1|word2|word3]...
  • @dbl 这无济于事,因为一旦最左边的替代匹配项,交替将返回,而 OP 想要“返回每个匹配项的出现”。
  • 点已被占用。我会留下评论,所以没有其他人会犯同样的错误......
  • 我的意思是通过参数传递一个 ArrayList 并验证它们每个的匹配。
  • 我认为如果你想要一个答案,你应该提供一些测试用例和预期的输出。尝试放足够多的东西:)

标签: java regex string search matcher


【解决方案1】:

所以第一个也是最简单的选择是使用您实际的 findTheWord() 方法并创建一个使用它的新方法:

public Map<String, Integer> findTheWords(String stringToCheck, List<String> words) {
    return words.stream().distinct()
            .collect(Collectors.toMap(Function.identity(), word -> findTheWord(stringToCheck, word)));
}

public Integer findTheWord(String stringToCheck, String regexString) {
    Pattern regexp = Pattern.compile("\\b" + regexString + "\\b");
    Matcher matcher = regexp.matcher(stringToCheck);

    int count = 0;
    while (matcher.find()) {
        count++;
    }
    return count;
}

问题在于,如果您使用大量单词来查找和大文本,因为它会为每个单词迭代给定的字符串。所以另一种方法是为所有单词创建一个正则表达式,并在结果映射中增加下一个找到的单词:

public Map<String, Integer> findTheWords(String stringToCheck, List<String> words) {
    Pattern regexp = Pattern.compile(words.stream().distinct().map(word -> "\\b" + word + "\\b").collect(Collectors.joining("|")));
    // creates a pattern like this: "\ba\b|\bb\b|\bc\b|\bd\b|\be\b"
    Matcher matcher = regexp.matcher(stringToCheck);
    Map<String, Integer> result = new HashMap<>();
    while (matcher.find()) {
        String word = matcher.group();
        result.put(word, result.getOrDefault(word, 0) + 1);
    }
    return result;
}

除此之外,您可能正在考虑使用Set 代替List,因为值是唯一的,因此无需在流上调用.distinct()

【讨论】:

    【解决方案2】:

    HashMap 作为参数,输入字符串作为键,正则表达式作为值,遍历所有条目,执行你的方法并返回一个 HashMap,匹配的词作为键,出现次数作为值。

     public HashMap<String, Integer> findTheWordsAndOccurences(HashMap<String, String> stringsAndRegex) throws IOException {
    
        HashMap<String, Integer> result = null;
    
        for (Map.Entry<String, String> entry : stringsAndRegex.entrySet()){
    
            String stringToCheck = entry.getKey();
            String regexString = entry.getValue();
            String matchString = "";
            int count = 0;
            Pattern regexp = Pattern.compile("\\b" + regexString + "\\b");
            Matcher matcher = regexp.matcher(stringToCheck);
    
            while (matcher.find()) {
                count++;
                matchString = matcher.group();
                System.out.println(matchString);
                result.put(matchString, count);
            }
        }
        return result;
    }
    

    【讨论】:

      猜你喜欢
      • 2012-03-10
      • 2022-12-05
      • 1970-01-01
      • 1970-01-01
      • 2015-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-13
      相关资源
      最近更新 更多