【问题标题】:Count uppercase characters in a word计算单词中的大写字符
【发布时间】:2015-05-20 15:35:31
【问题描述】:

我需要计算一个单词中有多少个大写字母。我该怎么做?

【问题讨论】:

  • 欢迎来到 Stack Overflow!发布问题时,请确保包含您尝试过的代码、所做的研究以及展示错误行为的具体、最小示例。然后,我们可以看看它并提供帮助。

标签: linux string shell uppercase


【解决方案1】:

我会使用grep -o '[A-Z]' 匹配大写,然后计算发生了多少次:

$ grep -o '[A-Z]' <<< "heLLo" | wc -l
2

或者甚至更好(thanks mklement0,总是提供很好的信息!),使用[[:upper:]],这样大写也将考虑在您的语言环境中定义的那些:

$ grep -o '[[:upper:]]' <<< "heLLo" | wc -l
2

【讨论】:

  • 聪明的解决方案;不过,我建议使用[[:upper:]] 而不是[A-Z],这样该命令也可以处理带重音的大写字符。
【解决方案2】:

我喜欢这个:

echo "$word" | tr -dc A-Z | wc -c

只需删除所有非大写字符并计算剩下的字符。

您可能更喜欢 tr -dc [:upper:],但我发现 A-Z 更易于使用。

【讨论】:

  • 不幸的是,这个优雅的解决方案只能在英语语言环境中正常工作,并错误地暗示A-Z[:upper:] 是等价的;看我的回答。
【解决方案3】:

tl;dr

对于一种区域设置感知并因此也适用于重音字符的解决方案,请使用:

echo "heLLÖ, world" | tr -dC '[:upper:]' | wc -m  # -> 3

需要进行更改才能正确处理非 ASCII 多字节编码字符。
请继续阅读以获取详细说明。


使上述命令具有区域感知能力的关键:

  • tr-C 选项使用基于字符 的补码,而-c 使用基于byte 的补码;而-c-C 在某些tr 实现中的行为可能相同,POSIX defines only -C as the locale-aware variant

  • [:upper:] 确保使用活动区域设置的 定义构成大写字符的内容,而A-Z 仅包含 unaccented(仅限 ASCII ) 从“A”到“Z”的字母。

  • wc-m 选项计数字符(在现在流行的UTF-8 编码中可能包含多个 字节);相比之下,-c 计数 bytes,在上面的示例中,它会报告 4 而不是预期的 3,因为 Ö 被编码为 2 个字节。


现在让我们看一下威廉的回答中的一句话:

您可能更喜欢tr -dc [:upper:],但我发现A-Z 更易于使用。

  • 这错误地表明[:upper:]A-Z 可以互换使用,并且选择其中一个只是偏好或方便的问题 - 但是,如上所述,[:upper:] 是区域设置感知的,而 @ 987654345@ 不是。
  • 另外,使用[:upper:] unquoted 使其受路径名扩展(通配)的影响,这意味着如果当前目录恰好包含名为:u、@987654349 的文件@、er[:upper:] 将扩展为它们的名称,这显然是不希望的。原因是未引用的[:upper:] 被shell 视为字符类
  • wc -c,计数 bytes,恰好与 A-Z 一起工作,因为根据定义,所有匹配的字母都是 单字节 字符;但切换到[:upper:] 以了解区域设置需要切换到wc -m,以便正确计算(可能是多字节)字符

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-06
    相关资源
    最近更新 更多