要找到多个正则表达式模式。 Java的

时间:2018-05-14 17:58:09

标签: java design-patterns matcher

我需要单独计算字符串中单词和句子的数量,我有两种方法可以正常工作:

    Pattern pattern = Pattern.compile("\\w+\\s|\\w+\\,|\\w+\\.|\\w+\\?|\\w+\\!*$");
    Matcher match1 = pattern.matcher(s);
    while(match1.find()) {
        counterWords++;
    }   

和句子:

    Pattern pattern = Pattern.compile("[^?!.][?!.]");
    Matcher match2 = pattern.matcher(s);
    while(match2.find()) {
        counterSentences++;
    }   

接下来的任务是再次计算它,但在一个循环中,所以我尝试了:

while(match1.find() || match2.find()){
    if(match1.find()){
        counterWords++;
    }
    if(match2.find()){
        counterSentences++;
    }

然而,该方法工作不正常,它正确计算句子,但字计数器是实际字数的2倍。很可能我完全不了解matcher.find()是如何工作的,有人可以解释我做错了什么吗? 谢谢。

2 个答案:

答案 0 :(得分:1)

要通过单个循环解决此问题,您需要匹配器找到单词或句末标记,然后告诉您它找到了哪个。这可以使用"捕获组"。

来完成
    String s = "Hello, user.  How many words and sentences are there?  Count them!";

    int words = 0;
    int sentences = 0;
    Pattern pattern = Pattern.compile("(\\w+)|([.?!])");
    Matcher matcher = pattern.matcher(s);

    while(matcher.find()) {
        if (matcher.group(1) != null)
            words++;
        else if (matcher.group(2) != null)
            sentences++;
    }

    System.out.printf("%d words and %d sentences%n", words, sentences);
  

11个单词和3个句子

正则表达式解释:

(\w+)|([.?!]) - 将\\翻译为\(___)________ - 捕获组#1 _\w+_________ - 一个或多个单词字符。
_____|_______ - 匹配表达式的第一部分或第二部分 ______(_____) - 捕获组#2 _______[.?!]_ - 句子终结者角色。

matcher.find()的第一次调用将与Hello匹配,将其记录为捕获组#1。下一个调用会跳过逗号和空格并匹配user,再次将其记录为捕获组#1。第三个调用匹配正则表达式第二部分中的句点(.),将其记录为捕获组#2。这将继续,直到感叹号(!)匹配。对matcher.find()的下一次调用返回false,因为找不到更多匹配项。

if语句检查是否填写了组#1或组#2,这决定了是否遇到了单词或句子终止符。

答案 1 :(得分:0)

每次调用find()都会搜索下一个匹配项,在你的组合while循环中,你在match1和match2的每个循环中调用find()两次,首先是while条件,然后是if条件,但是你只是增加第二次发现的计数器。

此外,因为你首先在while条件中调用find(),所以句子中的find()永远不会被调用,因为句子总是等于或多于句子,而且句子计数器将正常工作。