首页 > 解决方案 > 正则表达式匹配 - java

问题描述

我有一个要求 -
我有一个句子,he is a good programmer, he won 865 competitions, but sometimes he dont. What do you think? All test-cases should pass. Done-done?
该句子中的单词数是 21。
这是另一个示例:
jds dsaf lkdf kdsa fkldsf, adsbf ldka ads? asd bfdal ds bf[l. akf dhj ds 878 dwa WE DE 7475 dsfh ds RAMU 748 dj.
单词数:21
单词定义:
定义

我写了一个java代码来计算字符串中的单词。

public static int howMany(String sentence) {
    // Write your code here
        // int count = 0, i = 0;
        // if (sentence == null || sentence.isEmpty()) {
        //     return 0;
        // }
        // boolean isWord = false;
        // int EOL = sentence.length() - 1;
        // char[] chars = sentence.toCharArray();
        // for(i=0;i<chars.length;i++) {
        //     if(Character.isLetter(chars[i]) && i != EOL) {
        //         isWord = true;
        //     } else if (!Character.isLetter(chars[i]) && isWord) {
        //         count++;
        //         isWord = false;
        //     } else if (Character.isLetter(chars[i]) && i == EOL) {
        //         count++;
        //     }
        // }
        // return count;
        
        // StringTokenizer st = new StringTokenizer(sentence);
        // return st.countTokens();
        int count = 0;
        String regEx = "[\\w-]+";
        Pattern pattern = Pattern.compile(regEx);
        Matcher match = pattern.matcher(sentence);
        while(match.find()) {
            count++;
        }
        return count;
    }  

我的代码没有正确计算字数,这是另一个示例:
b? Dl )B 4(V! A. MK, YtG ](f 1m )CNxuNUR {PG?
字数:5。
但我的代码打印出 12。我该如何解决这个问题?

标签: javaregex

解决方案


您可以将此正则表达式用于您的自定义单词匹配:

(?<!\S)\pL+(?:-\pL+)*(?=\pP*(?:\h|$))

正则表达式演示

正则表达式详细信息:

  • (?<!\S): 否定后向断言我们在当前位置之前没有非空格
  • \pL+: 匹配任何字母的 1+
  • (?:-\pL+)*: 匹配 0 个或多个这样的 1+ 字母,用 a 分隔-
  • (?=\pP*(?:\h|$)): 肯定前瞻断言我们有 0 个或多个标点字符后跟空格或行尾

Java代码:

final String s = "jds dsaf lkdf kdsa fkldsf, adsbf ldka ads? asd bfdal ds bf[l. akf dhj ds 878  dwa WE DE 7475 dsfh ds  RAMU 748 dj., bf[l.";

final String re = "(?<!\\S)\\pL+(?:-\\pL+)*(?=\\p{P}*(?:\\h|$))";

final Matcher m = Pattern.compile(re).matcher(s);

int count = m.results().count();
//=> 21

/*
// or to get list of matching words
List<String> words = m.results()
   .map(MatchResult::group)
   .collect(Collectors.toList());

// => [jds, dsaf, lkdf, kdsa, fkldsf, adsbf, ldka, ads, asd, bfdal, ds, akf, dhj, ds, dwa, WE, DE, dsfh, ds, RAMU, dj]
*/

推荐阅读