要查找的多个正则表达式模式。 Java
Multiple regex patterns to find. Java
我需要分别计算字符串中单词和句子的数量,我有这两种工作正常的方法:
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() 是如何工作的,有人可以解释我做错了什么吗?
谢谢。
每次调用 find() 都会搜索下一个匹配项,在组合的 while 循环中,您在每个循环中为 match1 和 match2 调用 find() 两次,首先是在 while 条件中,然后是在 if 条件中,但您只是增加了第二次查找的计数器。
此外,由于您首先在 while 条件中为单词调用 find(),因此永远不会为句子调用 find(),因为单词总是等于或多于句子,并且句子计数器将正常工作。
要用一个循环解决这个问题,你需要你的匹配器找到单词或句末标记,然后告诉你它找到了哪个。这可以使用 "capturing groups".
来完成
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 words and 3 sentences
正则表达式解释:
(\w+)|([.?!])
- 在将 \
翻译成 \
之后
(___)________
- 捕获组 #1。
_\w+_________
- 一个或多个单词字符。
_____|_______
- 匹配表达式的第一部分或第二部分。
______(_____)
- 捕获组 #2。
_______[.?!]_
- 句子终止字符。
第一次调用 matcher.find()
将匹配 Hello
,将其记录为捕获组 #1。下一次调用跳过逗号和 space 并匹配 user
,再次将其记录为捕获组 #1。第三次调用匹配正则表达式第二部分中的句点 (.
),将其记录为捕获组 #2。这一直持续到感叹号 (!
) 匹配为止。下一次调用 matcher.find()
returns false,因为找不到更多匹配项。
if
语句检查组 #1 或组 #2 捕获是否已填写,这确定是否遇到单词或句子终止符。
我需要分别计算字符串中单词和句子的数量,我有这两种工作正常的方法:
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() 是如何工作的,有人可以解释我做错了什么吗? 谢谢。
每次调用 find() 都会搜索下一个匹配项,在组合的 while 循环中,您在每个循环中为 match1 和 match2 调用 find() 两次,首先是在 while 条件中,然后是在 if 条件中,但您只是增加了第二次查找的计数器。
此外,由于您首先在 while 条件中为单词调用 find(),因此永远不会为句子调用 find(),因为单词总是等于或多于句子,并且句子计数器将正常工作。
要用一个循环解决这个问题,你需要你的匹配器找到单词或句末标记,然后告诉你它找到了哪个。这可以使用 "capturing groups".
来完成 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 words and 3 sentences
正则表达式解释:
(\w+)|([.?!])
- 在将 \
翻译成 \
之后
(___)________
- 捕获组 #1。
_\w+_________
- 一个或多个单词字符。
_____|_______
- 匹配表达式的第一部分或第二部分。
______(_____)
- 捕获组 #2。
_______[.?!]_
- 句子终止字符。
第一次调用 matcher.find()
将匹配 Hello
,将其记录为捕获组 #1。下一次调用跳过逗号和 space 并匹配 user
,再次将其记录为捕获组 #1。第三次调用匹配正则表达式第二部分中的句点 (.
),将其记录为捕获组 #2。这一直持续到感叹号 (!
) 匹配为止。下一次调用 matcher.find()
returns false,因为找不到更多匹配项。
if
语句检查组 #1 或组 #2 捕获是否已填写,这确定是否遇到单词或句子终止符。