如何检查PHP中的字母是大写还是小写?
Posted
技术标签:
【中文标题】如何检查PHP中的字母是大写还是小写?【英文标题】:How to check if letter is upper or lower in PHP? 【发布时间】:2011-02-18 09:11:36 【问题描述】:我也有带有变音符号的 UTF-8 文本,并且想检查该文本的第一个字母是大写还是小写。如何做到这一点?
【问题讨论】:
为什么要检查一个字母是大写还是小写? @Elizabeth Buckwalter 因为我从这个文本中计算出其他文本,如果第一个字母高于我必须对第二个字母做同样的事情。 【参考方案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($w0))
print $w;
【讨论】:
这不适用于非拉丁字符,例如北欧 ÆØÅ。 这些是latin chars。ctype_upper
不适用于 非 ASCII 字符(包括那些北欧拉丁文,以及许多其他拉丁文,尤其是非拉丁文字符)。
感谢两位 cmets!但在问题中代表“带有变音符号的UTF-8”,它工作正常。如果您需要其他字符的功能,请使用 Artefacto 的答案。
此答案不正确有两个原因,因为您未能按照问题明确指出的那样测试多字节字符。 1. 您不能通过0
字节偏移量获取多字节字符——您只能访问该字母的第一个字节。 2.ctype_
没有为此任务提供必要的多字节支持。【参考方案3】:
我认为,与此处发布的其他解决方案相比,拨打preg_
是最直接、最简洁、最可靠的呼叫。
echo preg_match('~^\pLu~u', $string) ? 'upper' : 'lower';
我的模式分解:
~ # starting pattern delimiter
^ #match from the start of the input string
\pLu #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('~^\pLu~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
可以处理的类别中),您可能需要检查第一个字符是否有大小写变种:
来源:https://www.regular-expressions.info/unicode.html\pL& 或 \pCased_Letter:以小写和大写变体形式存在的字母(Ll、Lu 和 Lt 的组合)。
若要在SMALL
变体中包含罗马数字(“数字字母”),您可以在必要时将该额外范围添加到模式中。
https://www.fileformat.info/info/unicode/category/Nl/list.htm
代码:(Demo)
echo preg_match('~^[\pLu\x2160-\x216F]~u', $test) ? 'upper' : 'not upper';
【讨论】:
特别感谢 @Wiktor 帮助我在 fileformat.info 找到这些字符。【参考方案4】:试过了吗?
$str = 'the text to test';
if($str0 === strtoupper($str0))
echo 'yepp, its uppercase';
else
echo 'nope, its not upper case';
【讨论】:
$str0 与 $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 的第一个模式(~^\pLu~u
)很好,但对于不同的一般类别值(“Lu”大写字母类别除外),它会给出错误的结果。 *注意,他已经将答案底部的模式扩展到包括罗马数字。
例如
Ⅷ => ⅷ Ⅼ => ⅼ Ⅿ => ⅿ Ⅾ => ⅾ Ⅽ => ⅽ var_dump(preg_match('~^\pLu~u', 'Ⅷ') ? 'upper' : 'lower'); // Resutl: lower
var_dump(preg_match('~^\pLu~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 非常清楚需要处理“变音符号”。此仅代码答案不正确/不适当。以上是关于如何检查PHP中的字母是大写还是小写?的主要内容,如果未能解决你的问题,请参考以下文章