字符串中大写字母的正则表达式

11

我真的想不出为什么这个正则表达式不起作用。它应该在给定的字符串中找到大写字母并给出计数。欢迎任何想法。

这是单元测试代码:

public class RegEx {

    @Test
    public void testCountTheNumberOfUpperCaseCharacters() {
        String testStr = "abcdefghijkTYYtyyQ";
        String regEx = "^[A-Z]+$";

        Pattern pattern = Pattern.compile(regEx);

        Matcher matcher = pattern.matcher(testStr);

        System.out.printf("Found %d, of capital letters in %s%n", matcher.groupCount(), testStr);

    }
}
9个回答

20

这不起作用是因为您有两个问题:

  1. 正则表达式不正确,应使用"[A-Z]"用于ASCII字母或\p{Lu}用于Unicode大写字母。
  2. matcher.groupCount()之前没有调用while (matcher.find())

正确代码:

public void testCountTheNumberOfUpperCaseCharacters() {
    String testStr = "abcdefghijkTYYtyyQ";
    String regEx = "(\\p{Lu})";
    Pattern pattern = Pattern.compile(regEx);
    Matcher matcher = pattern.matcher(testStr);
    while (matcher.find())
        System.out.printf("Found %d, of capital letters in %s%n", 
          matcher.groupCount(), testStr);

}

更新:使用这个更简单的单行代码来计算字符串中Unicode大写字母的数量:

int countuc = testStr.split("(?=\\p{Lu})").length - 1;

groupCount 不会计算字符。答案总是相同的。 - Marko Topolnik
我并没有声明它计算字符。无论如何,让我编辑一下以回答那部分内容。 - anubhava
OP正在计算字符数,因此通过“正确的代码”你暗示了你的解决方案会计算字符数。 - Marko Topolnik
我在最近的更改中提供了一个更简单的代码来计算大写字母。 - anubhava
1
@anubhava:我尝试提交编辑,但SO不允许微小的、只有一个字符的编辑:你应该删除描述中的+(在你的2项列表中排名第1),以匹配你的代码。 - landru27

11
  1. 你没有在匹配器(matcher)上调用 matches find 方法。它没有做任何工作。

  2. getGroupCount是错误的方法。你的正则表达式没有捕获组,即使有,它也不会给你字符计数。

你应该使用find,但是使用另一个没有锚点的正则表达式,我还建议使用正确的Unicode字符类:"\\p{Lu}+"。在while (m.find())循环中使用它,并在每一步累加从m.group(0).length()获取的字符总数。


提到"\p{Lu}+"是我关注的关键部分。在看到你的答案之前,我已经开始了悬赏并且有另一个答案在我脑海中,但至少我会点赞你的答案。 - vektor

6

这应该能做到你想要的,

@Test
public void testCountTheNumberOfUpperCaseCharacters() {
  String testStr = "abcdefghijkTYYtyyQ";
  String regEx = "[A-Z]+";
  Pattern pattern = Pattern.compile(regEx);
  Matcher matcher = pattern.matcher(testStr);
  int count = 0;
  while (matcher.find()) {
    count+=matcher.group(0).length();
  }
  System.out.printf("Found %d, of capital letters in %s%n", count, testStr);
}

你可以通过使用 [A-Z]+count += matcher.group(0).length() 来加快速度。 - Marko Topolnik

3
它应该在给定的字符串中查找大写字母并给出计数。
不,它不应该这样做:'^'和'$'锚点阻止它这样做,强制查找由全部大写字符组成的非空字符串。
此外,在不定义组的表达式中,您不能期望组计数除了零(无匹配项)或一(单个匹配项)以外的任何值。
如果坚持使用正则表达式,请使用简单的'[A-Z]'表达式而没有锚点,并在循环中调用'matcher.find()'。然而,更好的方法是调用'Character.isUpperCase'对您的字符串的字符进行计数。
int count = 0;
for (char c : str.toCharArray()) {
    if (Character.isUpperCase(c)) {
        count++;
    }
}

你的解决方案和正则表达式哪个性能更好?@dasblinkenlight - MaheshVarma
@MaheshVarma 我没有进行基准测试,但我的解决方案应该会更快。 - Sergey Kalinichenko
这是大问题。[A-Z] 无法匹配 Č,在我看来(来自中欧),这是相当重要的 ;) 另一方面,Character.isUpperCase("Č") 正确地报告为 true - vektor
@vektor 如果你尝试搜索关于在任何语言中匹配大写字母+正则表达式的问题,那么成千上万的问题和答案都会引起你的注意。 - revo
@revo 可能可以实现,但当我搜索“仅保留字符串中的大写字母”或类似内容时,我发现了这个方法。虽然它似乎是在讨论一般情况,但它只适用于ASCII字符集。因此,我试图强调这一方面。 - vektor

1
你所写的模式是在行首和行尾之间寻找一个或多个大写字母……如果该行中有任何小写字符,则不匹配。

0

将正则表达式更改为[A-Z],以检查所有大写字母的出现

请参考以下示例,使用模式计算字符串中大写字母的数量

@Test
public void testCountTheNumberOfUpperCaseCharacters() {
    Pattern ptrn = Pattern.compile("[A-Z]");
    Matcher matcher = ptrn.matcher("ivekKVVV");
    int from = 0;
    int count = 0;
    while(matcher.find(from)) {
        count++;
        from = matcher.start() + 1;
    }
    System.out.println(count);
}

}


0

这里提供了一个适用于Java 9及更高版本的解决方案,它利用Matcher的results()方法返回结果流,从中可以计算出条目数。@Sergey Kalinichenko的建议是将^$锚点从正则表达式字符串中移除。

public class RegEx {
 @Test
 public void testCountTheNumberOfUpperCaseCharacters() {
    String testStr = "abcdefghijkTYYtyyQ";
    String regEx = "\\p{Lu}";

    Pattern pattern = Pattern.compile(regEx);
    Matcher matcher = pattern.matcher(testStr);
    long count = matcher.results().count();
    
    System.out.printf("Found %d of capital letters in %s%n", count, testStr);

 }
}

0
在这个例子中,我使用正则表达式来计算Java中给定字符串中大写字母和小写字母的数量。
import java.util.regex.*;
import java.util.Scanner;
import java.io.*;
public class CandidateCode {
    public static void main(String args[] ) throws Exception {
        Scanner sc= new Scanner(System.in);
    //  Reads the String of data entered in a line
        String str = sc.nextLine();

    //counts uppercase letteres in the given String 
        int countuc = str.split("([A-Z]+?)").length; 

    //counts lowercase letteres in the given String 
        int countlc = str.split("([a-z]+?)").length; 

        System.out.println("UpperCase count: "+countuc-1);
        System.out.println("LowerCase count: "+countlc-1);
   }
}

以下是有关编程的内容,请将其从英语翻译成中文。请仅返回翻译后的文本:不要只放代码,还要添加一些关于您的答案的描述。 - always-a-learner
谢谢你的评论,Ankit。我已经添加了一些关于代码的细节,希望它对理解代码有所帮助。 - ganesh konathala

0
你还可以使用Java正则表达式,例如:
.+[\p{javaUpperCase}].+ 

我的工作项目示例: 正则表达式结果图像

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接