我需要单独计算字符串中单词和句子的数量,我有两种方法可以正常工作:
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()是如何工作的,有人可以解释我做错了什么吗? 谢谢。
答案 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()永远不会被调用,因为句子总是等于或多于句子,而且句子计数器将正常工作。