问题
What is an ideal way to detected if a character is uppercase or lowercase, regardless of the fact of the current local language.
Is there a more direct function?
Assumptions: Set internal character encoding to UTF-8 & Local browser session is en-US,en;q=0.5 & Have installed Multibyte String extension. Do not use ctype_lower, or ctype_upper.
See below test code that should be multibyte compatible.
$encodingtype = 'utf8';
$charactervalue = mb_ord($character, $encodingtype);
$characterlowercase = mb_strtolower($character, $encodingtype) ;
$characterlowercasevalue = mb_ord(mb_strtolower($character, $encodingtype));
$characteruppercase = mb_strtoupper($character, $encodingtype);
$characteruppercasevalue = mb_ord(mb_strtoupper($character, $encodingtype));
// Diag Info
echo 'Input: ' . $character . "<br />";
echo 'Input Value: ' . $charactervalue = mb_ord($character, $encodingtype) . "<br />" . "<br />";
echo 'Lowercase: ' . $characterlowercase = mb_strtolower($character, $encodingtype) . "<br />";
echo 'Lowercase Value: ' . $characterlowercasevalue = mb_ord(mb_strtolower($character, $encodingtype)) . "<br />" . "<br />";
echo 'Uppercase: ' . $characteruppercase = mb_strtoupper($character, $encodingtype) . "<br />";
echo 'Uppercase Value: ' . $characteruppercasevalue = mb_ord(mb_strtoupper($character, $encodingtype)) . "<br />" . "<br />";
// Diag Info
if ($charactervalue == $characterlowercasevalue and $charactervalue != $characteruppercasevalue){
$uppercase = 0;
$lowercase = 1;
echo 'Is character is lowercase' . "<br />" . "<br />";
}
elseif ($charactervalue == $characteruppercasevalue and $charactervalue != $characterlowercasevalue ){
$uppercase = 1;
$lowercase = 0;
echo 'Character is uppercase' . "<br />" . "<br />";
}
else{
$uppercase = 0;
$lowercase = 0;
echo 'Character is neither lowercase or uppercase' . "<br />" . "<br />";
}
- // Test 1 A // Output-> Character is uppercase
- // Test 2 z // Output-> Character is lowercase
- // Test 3 + // Output-> Character is lowercase
- // Test 4 0 // Output-> Character is neither lowercase or uppercase
- // Test 5 ǻ // LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE // Output-> Character is lowercase
- // Test 6 Ͱ GREEK CAPITAL LETTER HETA // Output-> Character is uppercase
- // Test 7 '' NULL // Output-> Character is neither lowercase or uppercase
回答1:
I feel the most direct way would be to write a regex pattern to determine the character type.
In the following snippet, I'll search for uppercase letters (including unicode) in the first capture group, or lowercase letters in the second capture group. If the pattern makes no match, the character is not a letter.
A good reference for unicode letters in regex: https://regular-expressions.mobi/unicode.html
Writing two capture groups separated by a pipe means each type of letter will be slotted into a different indexed element in the output array. [0]
is the fullstring match (never used in this case, but its generation is unavoidable). [1]
will hold the uppercase match (or be empty when there is a lowercase match -- as a placeholding element). [2]
will hold the lowercase match -- it will only be generated if there is a lowercase match.
For this reason, we can assume the highest key in the matches array will determine the casing of the letter.
If the input character is a non-letter, preg_match()
will return the falsey result of 0
to represent the number of matches, when this happens 0
is used with the lookup to access neither
.
Code: (Demo) (Pattern 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
For anyone who is not yet on php7.3, you can call end() then key() like this:
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";
}
My first approach makes a minimum of one function call per test, and a maximum of two calls. My solution can be made into a one-liner by writing the preg_
call inside of $lookup[
and ]
, but I'm aiming for readability.
p.s. Here is another variation that I dreamed up. The difference is that preg_match()
always makes a match because of the final empty "alternative" (empty branch).
foreach ($tests as $test) {
preg_match('~(\p{Lu})|(\p{Ll})|~u', $test, $out);
echo "\n{$test}: " , $lookup[sizeof($out) - 1];
}
回答2:
Update:
Change all ctype_
function with direct comparison... and Support for Cirilic characters...
i like use function:
$str = array("a", "A", "+", "0", 'ǻ', 'Ͱ', "34", 442);
foreach ($str as $val) {
$replace = ['à' => 'a', 'á' => 'a', 'â' => 'a', 'ã' => 'a', 'ä' => 'a', 'ą' => 'a', 'å' => 'a', 'ā' => 'a', 'ă' => 'a', 'ǎ' => 'a', 'ǻ' => 'a', 'À' => 'A', 'Á' => 'A', 'Â' => 'A', 'Ã' => 'A', 'Ä' => 'A', 'Ą' => 'A', 'Å' => 'A', 'Ā' => 'A', 'Ă' => 'A', 'Ǎ' => 'A', 'Ǻ' => 'A', 'ç' => 'c', 'ć' => 'c', 'ĉ' => 'c', 'ċ' => 'c', 'č' => 'c', 'Ç' => 'C', 'Ć' => 'C', 'Ĉ' => 'C', 'Ċ' => 'C', 'Č' => 'C', 'ď' => 'd', 'đ' => 'd', 'Ð' => 'D', 'Ď' => 'D', 'Đ' => 'D', 'è' => 'e', 'é' => 'e', 'ê' => 'e', 'ë' => 'e', 'ę' => 'e', 'ē' => 'e', 'ĕ' => 'e', 'ė' => 'e', 'ě' => 'e', 'È' => 'E', 'É' => 'E', 'Ê' => 'E', 'Ë' => 'E', 'Ę' => 'E', 'Ē' => 'E', 'Ĕ' => 'E', 'Ė' => 'E', 'Ě' => 'E', 'ƒ' => 'f', 'ĝ' => 'g', 'ğ' => 'g', 'ġ' => 'g', 'ģ' => 'g', 'Ĝ' => 'G', 'Ğ' => 'G', 'Ġ' => 'G', 'Ģ' => 'G', 'ĥ' => 'h', 'ħ' => 'h', 'Ĥ' => 'H', 'Ħ' => 'H', 'ì' => 'i', 'í' => 'i', 'î' => 'i', 'ï' => 'i', 'ĩ' => 'i', 'ī' => 'i', 'ĭ' => 'i', 'į' => 'i', 'ſ' => 'i', 'ǐ' => 'i', 'Ì' => 'I', 'Í' => 'I', 'Î' => 'I', 'Ï' => 'I', 'Ĩ' => 'I', 'Ī' => 'I', 'Ĭ' => 'I', 'Į' => 'I', 'İ' => 'I', 'Ǐ' => 'I', 'ĵ' => 'j', 'Ĵ' => 'J', 'ķ' => 'k', 'Ķ' => 'K', 'ł' => 'l', 'ĺ' => 'l', 'ļ' => 'l', 'ľ' => 'l', 'ŀ' => 'l', 'Ł' => 'L', 'Ĺ' => 'L', 'Ļ' => 'L', 'Ľ' => 'L', 'Ŀ' => 'L', 'ñ' => 'n', 'ń' => 'n', 'ņ' => 'n', 'ň' => 'n', 'ʼn' => 'n', 'Ñ' => 'N', 'Ń' => 'N', 'Ņ' => 'N', 'Ň' => 'N', 'ò' => 'o', 'ó' => 'o', 'ô' => 'o', 'õ' => 'o', 'ö' => 'o', 'ð' => 'o', 'ø' => 'o', 'ō' => 'o', 'ŏ' => 'o', 'ő' => 'o', 'ơ' => 'o', 'ǒ' => 'o', 'ǿ' => 'o', 'Ò' => 'O', 'Ó' => 'O', 'Ô' => 'O', 'Õ' => 'O', 'Ö' => 'O', 'Ø' => 'O', 'Ō' => 'O', 'Ŏ' => 'O', 'Ő' => 'O', 'Ơ' => 'O', 'Ǒ' => 'O', 'Ǿ' => 'O', 'ŕ' => 'r', 'ŗ' => 'r', 'ř' => 'r', 'Ŕ' => 'R', 'Ŗ' => 'R', 'Ř' => 'R', 'ś' => 's', 'š' => 's', 'ŝ' => 's', 'ş' => 's', 'Ś' => 'S', 'Š' => 'S', 'Ŝ' => 'S', 'Ş' => 'S', 'ţ' => 't', 'ť' => 't', 'ŧ' => 't', 'Ţ' => 'T', 'Ť' => 'T', 'Ŧ' => 'T', 'ù' => 'u', 'ú' => 'u', 'û' => 'u', 'ü' => 'u', 'ũ' => 'u', 'ū' => 'u', 'ŭ' => 'u', 'ů' => 'u', 'ű' => 'u', 'ų' => 'u', 'ư' => 'u', 'ǔ' => 'u', 'ǖ' => 'u', 'ǘ' => 'u', 'ǚ' => 'u', 'ǜ' => 'u', 'Ù' => 'U', 'Ú' => 'U', 'Û' => 'U', 'Ü' => 'U', 'Ũ' => 'U', 'Ū' => 'U', 'Ŭ' => 'U', 'Ů' => 'U', 'Ű' => 'U', 'Ų' => 'U', 'Ư' => 'U', 'Ǔ' => 'U', 'Ǖ' => 'U', 'Ǘ' => 'U', 'Ǚ' => 'U', 'Ǜ' => 'U', 'ŵ' => 'w', 'Ŵ' => 'W', 'ý' => 'y', 'ÿ' => 'y', 'ŷ' => 'y', 'Ý' => 'Y', 'Ÿ' => 'Y', 'Ŷ' => 'Y', 'ż' => 'z', 'ź' => 'z', 'ž' => 'z', 'Ż' => 'Z', 'Ź' => 'Z', 'Ž' => 'Z', 'Ǽ' => 'A', 'ǽ' => 'a'];
$val = str_replace(array_keys($replace), $replace, $val);
if (strtoupper($val)!==$val) {
echo "<p class='text-success'>The string <b>$val</b> consists of lower Case letters .</p>";
} else {
echo "<p class='text-danger'>The string <b>$val</b> does not consist lower case letters.</p>";
}
}
but you need to have a dictionary special character; and not depending of lenguage setting...
Update
more short: with gateres List of character accent:
$str = array("a", "A", "+", "0", 'ǻ', 'Ͱ', "34", 442);
foreach ($str as $val) {
$charList = ['à' => 'a', 'á' => 'a', 'â' => 'a', 'ã' => 'a', 'ä' => 'a', 'ą' => 'a', 'å' => 'a', 'ā' => 'a', 'ă' => 'a', 'ǎ' => 'a', 'ǻ' => 'a', 'À' => 'A', 'Á' => 'A', 'Â' => 'A', 'Ã' => 'A', 'Ä' => 'A', 'Ą' => 'A', 'Å' => 'A', 'Ā' => 'A', 'Ă' => 'A', 'Ǎ' => 'A', 'Ǻ' => 'A', 'ç' => 'c', 'ć' => 'c', 'ĉ' => 'c', 'ċ' => 'c', 'č' => 'c', 'Ç' => 'C', 'Ć' => 'C', 'Ĉ' => 'C', 'Ċ' => 'C', 'Č' => 'C', 'ď' => 'd', 'đ' => 'd', 'Ð' => 'D', 'Ď' => 'D', 'Đ' => 'D', 'è' => 'e', 'é' => 'e', 'ê' => 'e', 'ë' => 'e', 'ę' => 'e', 'ē' => 'e', 'ĕ' => 'e', 'ė' => 'e', 'ě' => 'e', 'È' => 'E', 'É' => 'E', 'Ê' => 'E', 'Ë' => 'E', 'Ę' => 'E', 'Ē' => 'E', 'Ĕ' => 'E', 'Ė' => 'E', 'Ě' => 'E', 'ƒ' => 'f', 'ĝ' => 'g', 'ğ' => 'g', 'ġ' => 'g', 'ģ' => 'g', 'Ĝ' => 'G', 'Ğ' => 'G', 'Ġ' => 'G', 'Ģ' => 'G', 'ĥ' => 'h', 'ħ' => 'h', 'Ĥ' => 'H', 'Ħ' => 'H', 'ì' => 'i', 'í' => 'i', 'î' => 'i', 'ï' => 'i', 'ĩ' => 'i', 'ī' => 'i', 'ĭ' => 'i', 'į' => 'i', 'ſ' => 'i', 'ǐ' => 'i', 'Ì' => 'I', 'Í' => 'I', 'Î' => 'I', 'Ï' => 'I', 'Ĩ' => 'I', 'Ī' => 'I', 'Ĭ' => 'I', 'Į' => 'I', 'İ' => 'I', 'Ǐ' => 'I', 'ĵ' => 'j', 'Ĵ' => 'J', 'ķ' => 'k', 'Ķ' => 'K', 'ł' => 'l', 'ĺ' => 'l', 'ļ' => 'l', 'ľ' => 'l', 'ŀ' => 'l', 'Ł' => 'L', 'Ĺ' => 'L', 'Ļ' => 'L', 'Ľ' => 'L', 'Ŀ' => 'L', 'ñ' => 'n', 'ń' => 'n', 'ņ' => 'n', 'ň' => 'n', 'ʼn' => 'n', 'Ñ' => 'N', 'Ń' => 'N', 'Ņ' => 'N', 'Ň' => 'N', 'ò' => 'o', 'ó' => 'o', 'ô' => 'o', 'õ' => 'o', 'ö' => 'o', 'ð' => 'o', 'ø' => 'o', 'ō' => 'o', 'ŏ' => 'o', 'ő' => 'o', 'ơ' => 'o', 'ǒ' => 'o', 'ǿ' => 'o', 'Ò' => 'O', 'Ó' => 'O', 'Ô' => 'O', 'Õ' => 'O', 'Ö' => 'O', 'Ø' => 'O', 'Ō' => 'O', 'Ŏ' => 'O', 'Ő' => 'O', 'Ơ' => 'O', 'Ǒ' => 'O', 'Ǿ' => 'O', 'ŕ' => 'r', 'ŗ' => 'r', 'ř' => 'r', 'Ŕ' => 'R', 'Ŗ' => 'R', 'Ř' => 'R', 'ś' => 's', 'š' => 's', 'ŝ' => 's', 'ş' => 's', 'Ś' => 'S', 'Š' => 'S', 'Ŝ' => 'S', 'Ş' => 'S', 'ţ' => 't', 'ť' => 't', 'ŧ' => 't', 'Ţ' => 'T', 'Ť' => 'T', 'Ŧ' => 'T', 'ù' => 'u', 'ú' => 'u', 'û' => 'u', 'ü' => 'u', 'ũ' => 'u', 'ū' => 'u', 'ŭ' => 'u', 'ů' => 'u', 'ű' => 'u', 'ų' => 'u', 'ư' => 'u', 'ǔ' => 'u', 'ǖ' => 'u', 'ǘ' => 'u', 'ǚ' => 'u', 'ǜ' => 'u', 'Ù' => 'U', 'Ú' => 'U', 'Û' => 'U', 'Ü' => 'U', 'Ũ' => 'U', 'Ū' => 'U', 'Ŭ' => 'U', 'Ů' => 'U', 'Ű' => 'U', 'Ų' => 'U', 'Ư' => 'U', 'Ǔ' => 'U', 'Ǖ' => 'U', 'Ǘ' => 'U', 'Ǚ' => 'U', 'Ǜ' => 'U', 'ŵ' => 'w', 'Ŵ' => 'W', 'ý' => 'y', 'ÿ' => 'y', 'ŷ' => 'y', 'Ý' => 'Y', 'Ÿ' => 'Y', 'Ŷ' => 'Y', 'ż' => 'z', 'ź' => 'z', 'ž' => 'z', 'Ż' => 'Z', 'Ź' => 'Z', 'Ž' => 'Z', 'Ǽ' => 'A', 'ǽ' => 'a'];
$val = strtr($val, $charList);
if (strtoupper($val)!==$val) {
echo "<p class='text-success'>The string <b>$val</b> consists of lower Case letters .</p>";
} else {
echo "<p class='text-danger'>The string <b>$val</b> does not consist lower case letters.</p>";
}
}
Added and Style function:
function GetIfLoweCase($char) {
$charList = ['à' => 'a', 'á' => 'a', 'â' => 'a', 'ã' => 'a', 'ä' => 'a', 'ą' => 'a', 'å' => 'a', 'ā' => 'a', 'ă' => 'a', 'ǎ' => 'a', 'ǻ' => 'a', 'À' => 'A', 'Á' => 'A', 'Â' => 'A', 'Ã' => 'A', 'Ä' => 'A', 'Ą' => 'A', 'Å' => 'A', 'Ā' => 'A', 'Ă' => 'A', 'Ǎ' => 'A', 'Ǻ' => 'A', 'ç' => 'c', 'ć' => 'c', 'ĉ' => 'c', 'ċ' => 'c', 'č' => 'c', 'Ç' => 'C', 'Ć' => 'C', 'Ĉ' => 'C', 'Ċ' => 'C', 'Č' => 'C', 'ď' => 'd', 'đ' => 'd', 'Ð' => 'D', 'Ď' => 'D', 'Đ' => 'D', 'è' => 'e', 'é' => 'e', 'ê' => 'e', 'ë' => 'e', 'ę' => 'e', 'ē' => 'e', 'ĕ' => 'e', 'ė' => 'e', 'ě' => 'e', 'È' => 'E', 'É' => 'E', 'Ê' => 'E', 'Ë' => 'E', 'Ę' => 'E', 'Ē' => 'E', 'Ĕ' => 'E', 'Ė' => 'E', 'Ě' => 'E', 'ƒ' => 'f', 'ĝ' => 'g', 'ğ' => 'g', 'ġ' => 'g', 'ģ' => 'g', 'Ĝ' => 'G', 'Ğ' => 'G', 'Ġ' => 'G', 'Ģ' => 'G', 'ĥ' => 'h', 'ħ' => 'h', 'Ĥ' => 'H', 'Ħ' => 'H', 'ì' => 'i', 'í' => 'i', 'î' => 'i', 'ï' => 'i', 'ĩ' => 'i', 'ī' => 'i', 'ĭ' => 'i', 'į' => 'i', 'ſ' => 'i', 'ǐ' => 'i', 'Ì' => 'I', 'Í' => 'I', 'Î' => 'I', 'Ï' => 'I', 'Ĩ' => 'I', 'Ī' => 'I', 'Ĭ' => 'I', 'Į' => 'I', 'İ' => 'I', 'Ǐ' => 'I', 'ĵ' => 'j', 'Ĵ' => 'J', 'ķ' => 'k', 'Ķ' => 'K', 'ł' => 'l', 'ĺ' => 'l', 'ļ' => 'l', 'ľ' => 'l', 'ŀ' => 'l', 'Ł' => 'L', 'Ĺ' => 'L', 'Ļ' => 'L', 'Ľ' => 'L', 'Ŀ' => 'L', 'ñ' => 'n', 'ń' => 'n', 'ņ' => 'n', 'ň' => 'n', 'ʼn' => 'n', 'Ñ' => 'N', 'Ń' => 'N', 'Ņ' => 'N', 'Ň' => 'N', 'ò' => 'o', 'ó' => 'o', 'ô' => 'o', 'õ' => 'o', 'ö' => 'o', 'ð' => 'o', 'ø' => 'o', 'ō' => 'o', 'ŏ' => 'o', 'ő' => 'o', 'ơ' => 'o', 'ǒ' => 'o', 'ǿ' => 'o', 'Ò' => 'O', 'Ó' => 'O', 'Ô' => 'O', 'Õ' => 'O', 'Ö' => 'O', 'Ø' => 'O', 'Ō' => 'O', 'Ŏ' => 'O', 'Ő' => 'O', 'Ơ' => 'O', 'Ǒ' => 'O', 'Ǿ' => 'O', 'ŕ' => 'r', 'ŗ' => 'r', 'ř' => 'r', 'Ŕ' => 'R', 'Ŗ' => 'R', 'Ř' => 'R', 'ś' => 's', 'š' => 's', 'ŝ' => 's', 'ş' => 's', 'Ś' => 'S', 'Š' => 'S', 'Ŝ' => 'S', 'Ş' => 'S', 'ţ' => 't', 'ť' => 't', 'ŧ' => 't', 'Ţ' => 'T', 'Ť' => 'T', 'Ŧ' => 'T', 'ù' => 'u', 'ú' => 'u', 'û' => 'u', 'ü' => 'u', 'ũ' => 'u', 'ū' => 'u', 'ŭ' => 'u', 'ů' => 'u', 'ű' => 'u', 'ų' => 'u', 'ư' => 'u', 'ǔ' => 'u', 'ǖ' => 'u', 'ǘ' => 'u', 'ǚ' => 'u', 'ǜ' => 'u', 'Ù' => 'U', 'Ú' => 'U', 'Û' => 'U', 'Ü' => 'U', 'Ũ' => 'U', 'Ū' => 'U', 'Ŭ' => 'U', 'Ů' => 'U', 'Ű' => 'U', 'Ų' => 'U', 'Ư' => 'U', 'Ǔ' => 'U', 'Ǖ' => 'U', 'Ǘ' => 'U', 'Ǚ' => 'U', 'Ǜ' => 'U', 'ŵ' => 'w', 'Ŵ' => 'W', 'ý' => 'y', 'ÿ' => 'y', 'ŷ' => 'y', 'Ý' => 'Y', 'Ÿ' => 'Y', 'Ŷ' => 'Y', 'ż' => 'z', 'ź' => 'z', 'ž' => 'z', 'Ż' => 'Z', 'Ź' => 'Z', 'Ž' => 'Z', 'Ǽ' => 'A', 'ǽ' => 'a'];
$char = strtr($char, $charList);
if (strtoupper($char) !== $char) {
return true;
} else {
return false;
}
}
$str = array("a", "A", "+", "0", 'ǻ', 'Ͱ', "34", 442);
foreach ($str as $val) {
if (GetIfLoweCase($val)) {
echo "<p class='text-success'>The string <b>$val</b> consists of lower Case letters .</p>";
} else {
echo "<p class='text-danger'>The string <b>$val</b> does not consist lower case letters.</p>";
}
}
来源:https://stackoverflow.com/questions/55974931/what-is-best-way-to-test-uppercase-or-lowercase-type-of-a-given-character-in-php