我觉得最直接的方法是编写正则表达式模式来确定字符类型。
在下面的代码片段中,我将在第一个捕获组中搜索大写字母(包括 unicode),或在第二个捕获组中搜索小写字母。如果模式不匹配,则该字符不是字母。
正则表达式中 unicode 字母的一个很好的参考:https://regular-expressions.mobi/unicode.html
写入由管道分隔的两个捕获组意味着每种类型的字母将被插入到输出数组中的不同索引元素中。[0]
是全字符串匹配(在本例中从未使用过,但它的生成是不可避免的)。[1]
将保存大写匹配(或者当存在小写匹配时为空——作为占位元素)。[2]
将保存小写匹配——只有在存在小写匹配时才会生成。
因此,我们可以假设 matches 数组中的最高键将决定字母的大小写。
如果输入的字符是非字母,preg_match()
将返回错误结果0
表示匹配的数量,当发生这种情况时0
与查找一起使用来访问neither
.
Code: (Demo) (图案演示)
$lookup = ['neither', 'upper', 'lower'];
$tests = ['A', 'z', '+', '0', 'ǻ', 'Ͱ', null];
foreach ($tests as $test) {
$index = preg_match('~(\p{Lu})|(\p{Ll})~u', $test, $out) ? array_key_last($out) : 0;
echo "{$test}: {$lookup[$index]}\n";
}
Output:
A: upper
z: lower
+: neither
0: neither
ǻ: lower
Ͱ: upper
: neither
对于尚未使用 php7.3 的任何人,您可以致电结束()然后键()像这样:
Code: (Demo)
foreach ($tests as $test) {
if (preg_match('~(\p{Lu})|(\p{Ll})~u', $test, $out)) {
end($out); // advance pointer to final element
$index = key($out);
} else {
$index = 0;
}
echo "{$test}: {$lookup[$index]}\n";
}
我的第一种方法每次测试至少进行一次函数调用,最多进行两次调用。我的解决方案可以通过写成一行preg_
调用里面的$lookup[
and ]
,但我的目标是可读性。
附注这是我想象的另一种变化。不同之处在于preg_match()
由于最后一个空的“替代”(空分支),总是会匹配。
foreach ($tests as $test) {
preg_match('~(\p{Lu})|(\p{Ll})|~u', $test, $out);
echo "\n{$test}: " , $lookup[sizeof($out) - 1];
}