【问题标题】:Is there an existing library method that checks if a String is all upper case or lower case in Java?是否有现有的库方法可以检查 Java 中的 String 是全部大写还是小写?
【发布时间】:2009-03-24 14:08:06
【问题描述】:

我知道在 Java 和其他框架(如 Apache commons lang)中有很多 upper() 方法,它们将字符串转换为全部大写。

有没有提供像isUpper(String s)isLower(String s)这样的方法来检查String中所有字符是大写还是小写的通用库?

编辑:

关于转换为 Upper 并与此进行比较的许多很好的答案。我想我应该更具体一点,并说我已经想到了这一点,但我希望能够使用现有的方法。

关于在 apache.commons.lang.StringUtils 中可能包含此内容的好评论。 甚至有人提交了补丁(20090310)。希望我们很快就会看到这一点。 https://issues.apache.org/jira/browse/LANG-471

编辑:

我需要这种方法的目的是将有时全大写的酒店名称大写。如果它们都是小写或大写,我只想将它们大写。 我确实遇到了一些帖子中提到的非字母字符的问题,并最终做了这样的事情:

private static boolean isAllUpper(String s) {
    for(char c : s.toCharArray()) {
       if(Character.isLetter(c) && Character.isLowerCase(c)) {
           return false;
        }
    }
    return true;
}

这个讨论和不同的解决方案(有不同的问题)清楚地表明,在 commons.lang 中需要一个好的可靠的 isAllUpper(String s) 方法

在那之前,我想myString.toUpperCase().equals(myString) 是最好的选择。

【问题讨论】:

标签: java string


【解决方案1】:

现在在 StringUtils isAllUpperCase

【讨论】:

  • “它不适用于这个字符串”,猜猜为什么:)
  • 按照文档完美运行;有一个例子: StringUtils.isAllUpperCase(" ") = false
  • 这不是越野车,如果这就是你的意思。只是它在自然语言处理中不太可能有用。它也很容易修复(请参阅Simon's 答案)。
【解决方案2】:

不幸的是,它不是库函数,但很容易实现。如果效率是一个问题,这可能比 s.toUpperCase().equals(s) 更快,因为它可以提前退出。

public static boolean isUpperCase(String s)
{
    for (int i=0; i<s.length(); i++)
    {
        if (!Character.isUpperCase(s.charAt(i)))
        {
            return false;
        }
    }
    return true;
}

编辑: 正如其他发帖人和评论者所指出的,我们需要考虑字符串包含非字母字符时的行为:isUpperCase("HELLO1") 应该返回 true 还是 false?上面的函数将返回 false,因为 '1' 不是大写字符,但这可能不是您想要的行为。在这种情况下返回 true 的替代定义是:

public static boolean isUpperCase2(String s)
{
    for (int i=0; i<s.length(); i++)
    {
        if (Character.isLowerCase(s.charAt(i)))
        {
            return false;
        }
    }
    return true;
}

【讨论】:

  • 很棒的小功能,喜欢!
  • +1 isUpperCase2 应该是公认的答案。 StringUtils.isAllUpperCase 的当前答案对于明显大写的自然语言句子(例如“WON'T WORK”)失败,因为 ' 不是大写字符。
  • 上面的第二种方法应该更恰当地称为isNotPartiallyLowerCase或类似的东西,因为它不包括大写字母,不包括小写字母。所以我相信“123”是真的,因为它不包含任何小写字母。
【解决方案3】:

这个if条件可以得到预期的结果:

String input = "ANYINPUT";

if(input.equals(input.toUpperCase())
{
   // input is all upper case
}
else if (input.equals(input.toLowerCase())
{
   // input is all lower case
}
else
{
   // input is mixed case
}

【讨论】:

  • 这不处理任何可能的字符串。相反,这只处理已知的字符串子集,我假设 OP 想要一些适用于任何字符串的东西
  • @sigmavirus24 哪种情况处理失败?
【解决方案4】:

我不知道。

您可以复制字符串并将副本转换为小写/大写并与原始字符串进行比较。

或者创建一个循环来检查单个字符是小写还是大写。

【讨论】:

    【解决方案5】:

    此方法可能比比较字符串与其大写版本更快,因为它只需要 1 遍:

    public static boolean isUpper(String s)
    {
        for(char c : s.toCharArray())
        {
            if(! Character.isUpperCase(c))
                return false;
        }
    
        return true;
    }
    

    请注意,不同字符集可能存在一些本地化问题。我没有任何第一手经验,但我认为在某些语言(如土耳其语)中,不同的小写字母可以映射到同一个大写字母。

    【讨论】:

    • 请注意 toCharArray() 将创建字符串的副本。我建议改用旧的 chatAt()。
    • 在土耳其语中大小写和往常一样,只是映射与其他语言环境不同。具体来说,“i”在切换大小写时是否有变音符号切换。德语 eszet 变为大写时会转换为两个字符。
    • 如果字符串中包含非字母字符(如“2”),此方法不是很有用。它可能不适用于没有大写/小写字母或补充范围字符(32 位代码点)的字母。
    • @McDowell 被接受的答案,提到StringUtils.isAllUpperCase,有同样的缺陷。诸如“WON'T WORK”之类的英文大写句子将返回 false。
    【解决方案6】:

    Guava 的CharMatchers 倾向于为这类问题提供非常有表现力和高效的解决方案。

    CharMatcher.javaUpperCase().matchesAllOf("AAA"); // true
    CharMatcher.javaUpperCase().matchesAllOf("A SENTENCE"); // false
    CharMatcher.javaUpperCase().or(CharMatcher.whitespace()).matchesAllOf("A SENTENCE"); // true
    CharMatcher.javaUpperCase().or(CharMatcher.javaLetter().negate()).matchesAllOf("A SENTENCE"); // true
    CharMatcher.javaLowerCase().matchesNoneOf("A SENTENCE"); // true
    

    com.google.common.base.CharMatcher.* 的静态导入可以帮助使这些更简洁。

    javaLowerCase().matchesNoneOf("A SENTENCE"); // true
    

    【讨论】:

    • 所有这些都是自 Guava 24 弃用以来。
    • @kaba713 很好的呼唤。 Guava 开发人员现在推荐使用 ICU4J,因为它具有出色的 unicode 支持。此页面上的答案均不承认代理对。请写一个使用ICU4J的答案,我无法弄清楚API!
    • Guava 已被弃用,这不再是最佳答案
    • @MikeFHay 您现在可能已经找到了解决方案,但如果其他人有同样的问题,请查看我的回答:stackoverflow.com/a/67118483/1303158
    【解决方案7】:

    试试这个,可能会有帮助。

    import java.util.regex.Pattern;
    
    private static final String regex ="^[A-Z0-9]"; //alpha-numeric uppercase
    public static boolean isUpperCase(String str){
        return Pattern.compile(regex).matcher(str).find();
    }
    

    使用此代码,我们只需更改正则表达式。

    【讨论】:

    • 私有静态最终字符串 VALID_CODE ="^[A-Z0-9]+$";
    • 给定的正则表达式只检查字符串的开头。
    • 只需str.matches("[A-Z0-9]+") 会更短且更易于阅读。而且由于String#matches 隐式添加^...&amp; 以匹配整个字符串,因此您也不需要@TimP 建议的完整正则表达式^[A-Z0-9]+$(您当前的代码确实需要它,因为您只检查是否字符串以大写开头,而不是完全大写)。
    • 最好将编译后的模式存储为常量并在您的方法中使用它,而不是为每次调用编译正则表达式。除了更好的性能之外,您还可以获得更短的方法体和更精确的常量类型(ˋPatternˋ 而不是 ˋStringˋ)。
    【解决方案8】:

    我意识到这个问题已经很老了,但接受的答案使用了一个已弃用的 API,还有一个关于如何使用 ICU4J 来解决的问题。我就是这样做的:

    s.chars().filter(UCharacter::isLetter).allMatch(UCharacter::isUpperCase)
    

    【讨论】:

    • 我不确定是使用isUpperCase() 还是isUUpperCase()。对于我尝试过的英文字符串,它们都返回 true。如果对ICU4J有更多了解的人可以澄清一下,将不胜感激。
    【解决方案9】:

    如果您希望输入字符串很短,可以按照您的建议使用myString.toUpperCase().equals(myString)。它简短而富有表现力。

    但你也可以使用流:

    boolean allUpper = myString.chars().noneMatch(Character::isLowerCase);
    

    【讨论】:

      【解决方案10】:

      你可以使用 java.lang.Character.isUpperCase() 然后您可以轻松编写一个方法来检查您的字符串是否为大写(带有一个简单的循环)。

      将消息 toUpperCase() 发送到您的字符串,然后检查结果是否等于您的字符串可能会更慢。

      【讨论】:

      • 这需要更多的阐述。不小心使用isUpperCase 将导致有缺陷的实现。查看其他答案(及其陷阱)。
      【解决方案11】:

      这是我想出的一个有点通用的解决方案,因为它不需要任何库或特殊导入,应该适用于任何版本的 Java,只需要一次通过,并且应该比任何基于正则表达式的解决方案快得多:

      public static final boolean isUnicaseString(String input) {
        char[] carr = input.toCharArray();
        // Get the index of the first letter
        int i = 0;
        for (; i < carr.length; i++) {
          if (Character.isLetter(carr[i])) {
            break;
          }
        }
        // If we went all the way to the end above, then return true; no case at all is technically unicase
        if (i == carr.length) {
          return true;
        }
        // Determine if first letter is uppercase
        boolean firstUpper = Character.isUpperCase(carr[i]);
        for (; i < carr.length; i++) {
          // Check each remaining letter, stopping when the case doesn't match the first
          if (Character.isLetter(carr[i]) && Character.isUpperCase(carr[i]) != firstUpper) {
            return false;
          }
        }
        // If we didn't stop above, then it's unicase
        return true;
      }
      

      【讨论】:

        猜你喜欢
        • 2019-08-29
        • 2020-04-05
        • 1970-01-01
        • 2021-08-12
        • 2018-06-17
        • 2015-04-23
        • 2023-02-11
        • 2011-02-18
        • 2012-01-03
        相关资源
        最近更新 更多