【问题标题】:How to check if letter is upper or lower in PHP?如何检查PHP中的字母是大写还是小写?
【发布时间】:2011-02-18 09:11:36
【问题描述】:

我也有带有变音符号的 UTF-8 文本,并且想检查该文本的第一个字母是大写还是小写。如何做到这一点?

【问题讨论】:

  • 为什么要检查一个字母是大写还是小写?
  • @Elizabeth Buckwalter 因为我从这个文本中计算出其他文本,如果第一个字母高于我必须对第二个字母做同样的事情。

标签: php string utf-8


【解决方案1】:
function starts_with_upper($str) {
    $chr = mb_substr ($str, 0, 1, "UTF-8");
    return mb_strtolower($chr, "UTF-8") != $chr;
}

请注意,mb_substr 是正确隔离第一个字符所必需的。

Working Demo Online

【讨论】:

  • 并不总是有效。有些 Unicode 字符是大写字母(即 Lu 类别),但没有小写映射。大多数情况下,数学粗体/斜体/双打字母。
  • @dan04 这是一个很好的观点。最重要的是,还有标题案例(LT)。但是,mbstring 扩展不会向用户空间公开函数来测试这些属性。很遗憾,因为功能在那里——见svn.php.net/viewvc/php/php-src/trunk/ext/mbstring/…
  • @dan04 这个函数将如何处理这种情况?
  • 澄清一下,“Unicode 标准中有超过 100 个小写字母没有直接对应的大写字母。” -- unicode.org/faq/casemap_charprop.html
  • 赞成,很好的答案,谢谢!为您的代码添加了一个工作演示,干杯!
【解决方案2】:

使用ctype_upper检查大写:

$a = array("Word", "word", "wOrd");

foreach($a as $w)
{
    if(ctype_upper($w{0}))
    {
        print $w;
    }
}

【讨论】:

  • 这不适用于非拉丁字符,例如北欧 ÆØÅ。
  • 这些是latin charsctype_upper 不适用于 非 ASCII 字符(包括那些北欧拉丁文,以及许多其他拉丁文,尤其是非拉丁文字符)。
  • 感谢两位 cmets!但在问题中代表“带有变音符号的UTF-8”,它工作正常。如果您需要其他字符的功能,请使用 Artefacto 的答案。
  • 此答案不正确有两个原因,因为您未能按照问题明确指出的那样测试多字节字符。 1. 您不能通过0 字节偏移量获取多字节字符——您只能访问该字母的第一个字节。 2.ctype_没有为此任务提供必要的多字节支持。
【解决方案3】:

我认为,与此处发布的其他解决方案相比,拨打preg_ 是最直接、最简洁、最可靠的呼叫。

echo preg_match('~^\p{Lu}~u', $string) ? 'upper' : 'lower';

我的模式分解:

~      # starting pattern delimiter 
^      #match from the start of the input string
\p{Lu} #match exactly one uppercase letter (unicode safe)
~      #ending pattern delimiter 
u      #enable unicode matching

ctype_< 'a' 在这一系列测试中失败时请注意。

代码:(Demo)

$tests = ['âa', 'Bbbbb', 'Éé', 'iou', 'Δδ'];

foreach ($tests as $test) {
    echo "\n{$test}:";
    echo "\n\tPREG:  " , preg_match('~^\p{Lu}~u', $test)      ? 'upper' : 'lower';
    echo "\n\tCTYPE: " , ctype_upper(mb_substr($test, 0, 1))  ? 'upper' : 'lower';
    echo "\n\t< a:   " , mb_substr($test, 0, 1) < 'a'         ? 'upper' : 'lower';

    $chr = mb_substr ($test, 0, 1, "UTF-8");
    echo "\n\tMB:    " , mb_strtoupper($chr, "UTF-8") == $chr ? 'upper' : 'lower';
}

输出:

âa:
    PREG:  lower
    CTYPE: lower
    < a:   lower
    MB:    lower
Bbbbb:
    PREG:  upper
    CTYPE: upper
    < a:   upper
    MB:    upper
Éé:               <-- trouble
    PREG:  upper
    CTYPE: lower  <-- uh oh
    < a:   lower  <-- uh oh
    MB:    upper
iou:
    PREG:  lower
    CTYPE: lower
    < a:   lower
    MB:    lower
Δδ:               <-- extended beyond question scope
    PREG:  upper  <-- still holding up
    CTYPE: lower
    < a:   lower
    MB:    upper  <-- still holding up

如果有人需要区分大写字母、小写字母和非字母,请参阅this post


这可能将这个问题的范围扩展得太远,但是如果您的输入字符特别松散(它们可能不存在于Lu 可以处理的类别中),您可能需要检查第一个字符是否有大小写变种:

\p{L&} 或 \p{Cased_Letter}:以小写和大写变体形式存在的字母(Ll、Lu 和 Lt 的组合)。

若要在SMALL 变体中包含罗马数字(“数字字母”),您可以在必要时将该额外范围添加到模式中。

https://www.fileformat.info/info/unicode/category/Nl/list.htm

代码:(Demo)

echo preg_match('~^[\p{Lu}\x{2160}-\x{216F}]~u', $test) ? 'upper' : 'not upper';

【讨论】:

  • 特别感谢 @Wiktor 帮助我在 fileformat.info 找到这些字符。
【解决方案4】:

试过了吗?

$str = 'the text to test';
if($str{0} === strtoupper($str{0})) {
   echo 'yepp, its uppercase';
}
else{
   echo 'nope, its not upper case';
}

【讨论】:

  • $str{0} 与 $str[0] 相同。有时 substr(string, start, length) 在 start 或 length 为负数时很有用。
  • 此答案不正确有两个原因,因为您未能按照问题明确指出的那样测试多字节字符。 1. 您不能通过0 字节偏移量获取多字节字符——您只能访问该字母的第一个字节。 2.strtoupper没有为此任务提供必要的多字节支持。
【解决方案5】:

在 Kohana 2 自动加载功能中使用:

echo $char < 'a' ? 'uppercase' : 'lowercase';

当一个字符串字符被转换为整数时,它会计算为它的 ASCII 数字。如您所知,在 ASCII 表中首先有一些控制字符和其他字符。然后是拉丁字母的大写字母。然后是拉丁字母中的小写字母。因此,您可以轻松检查一个字母的代码是小于还是大于拉丁小字符a

顺便说一句,这比使用正则表达式的解决方案快两倍左右。

【讨论】:

  • 即使是utf也是最快的
  • 此答案不正确,因为您未能按照问题明确说明测试多字节字符。
【解决方案6】:

请注意,PHP 提供了 ctype 系列,如 ctype_upper

您必须首先通过setLocale() 正确设置语言环境,才能使其与UTF-8 一起使用。
例如,请参阅ctype_alpha 上的评论。

用法:

if ( ctype_upper( $str[0] )) {
    // deal with 1st char of $str is uppercase
}

【讨论】:

  • 不适用于 UTF-8。对 php.net 的评论有 -2 票(否决)。试试:setlocale(LC_ALL, 'ru_RU.utf-8'); return ctype_upper('П') === false;
  • 在动态环境中让setLocale() 设置正确可能很麻烦。更重要的是,您不能通过第一个字节偏移量访问整个多字节字符。这个答案不正确/不稳定。 3v4l.org/38R6f
【解决方案7】:

我不想让数字和其他人成为大字符,所以我使用:

if(preg_match('/[A-Z]$/',$char)==true)
{
   // this must be an upper char
   echo $char
}

【讨论】:

  • 这个答案是不正确的,因为: 1.它不是检查第一个字符,而是检查最后一个字符。 2.它没有像问题明确指出的那样尝试匹配多字节字符。
【解决方案8】:

刚刚呢:

if (ucfirst($string) == $string) {dosomething();}

【讨论】:

  • 没有。这对于提出的问题是不合适/不正确的。 3v4l.org/1GpYX
【解决方案9】:

如果你想要一个好的功能,我用过这个:

function _is_upper ($in_string)
{
    return($in_string === strtoupper($in_string) ? true : false);
}

那就打电话吧..

if (_is_upper($mystring))
{
  // Do....
}

【讨论】:

  • 您的解决方案对于提出的问题不合适/不正确。您的解决方案不支持问题中明确说明的“变音符号”。
【解决方案10】:

PHP 7 中另一个可能的解决方案是使用IntlChar

IntlChar 提供对许多实用方法的访问,这些方法可用于访问有关 Unicode 字符的信息。

$tests = ['âa', 'Bbbbb', 'Éé', 'iou', 'Δδ'];

foreach ($tests as $test) {
    echo "{$test}:\t";
    echo IntlChar::isUUppercase(mb_substr($test, 0, 1)) ? 'upper' : 'lower';
    echo PHP_EOL; 
}

输出:

âa:     lower
Bbbbb:  upper
Éé:     upper
iou:    lower
Δδ:     upper

虽然@mickmackusa 的第一个模式(~^\p{Lu}~u)很好,但对于不同的一般类别值(“Lu”大写字母类别除外),它会给出错误的结果。 *注意,他已经将答案底部的模式扩展到包括罗马数字。

例如

  • Ⅷ => ⅷ
  • Ⅼ => ⅼ
  • Ⅿ => ⅿ
  • Ⅾ => ⅾ
  • Ⅽ => ⅽ

 var_dump(preg_match('~^\p{Lu}~u', 'Ⅷ') ? 'upper' : 'lower'); // Resutl: lower
 var_dump(preg_match('~^\p{Lu}~u', 'ⅷ') ? 'upper' : 'lower'); // Result: lower

但是

var_dump(IntlChar::isUUppercase(mb_substr('Ⅷ', 0, 1)) ? 'upper' : 'lower'); // Result: upper    
var_dump(IntlChar::isUUppercase(mb_substr('ⅷ', 0, 1)) ? 'upper' : 'lower'); // Result: lower   

如果要检查也是大写但具有不同一般类别值的字符,请确保使用IntlChar::isUUppercase 而不是IntlChar::isupper

注意:这个库依赖于intl(国际化扩展)

【讨论】:

  • @mickmackusa 真的,我喜欢你的方法,我认为它稍微快一些。但我不会将正则表达式用于这么简单的任务。
  • 您宁愿使用mb_ 函数而不是依赖于库的类方法?好吧,你的选择。当它提供最直接的方法并且不会丢失合理的性能时,我总是喜欢正则表达式。为研究人员提供选择是件好事。
  • @mickmackusa 是的,如果这会增加我的代码可读性。同样,您的解决方案很棒,但是如果没有您的模式分解,像我这样愚蠢的人可能需要更多时间才能获得它。
  • 下班后我会调查你的比较。谢谢你ping我。你是说我的答案在罗马数字上失败了?
  • @mickmackusa 是的,一些罗马数字和一些 (So) 类别有大小写变体。而且我认为处理这些情况也会很有用。
【解决方案11】:
if(ctype_upper(&value)){
    echo 'uppercase';
}
else {
    echo 'not upper case';
}

【讨论】:

  • ctype_ 没有为此任务提供必要的多字节支持。 OP 非常清楚需要处理“变音符号”。此仅代码答案不正确/不适当。
猜你喜欢
  • 2014-02-12
  • 1970-01-01
  • 1970-01-01
  • 2018-06-17
  • 2015-04-23
  • 2011-09-15
  • 1970-01-01
  • 2021-08-12
  • 2012-01-03
相关资源
最近更新 更多