文字列「HET1200テキスト文字列」があり、「HET1200テキスト文字列」に変更する必要があるとします。エンコーディングはUTF-8になります。
どうやってやるの?現在使用していますmb_convert_case($string, MB_CASE_TITLE, "UTF-8");
が、「HET1200」が「Het1200」に変わります。
例外を指定することもできますが、それだけでは不十分です。だから私はむしろすべて大文字のままで大文字のままにします。
ありがとう :)
mb_convert_case
OK、できるだけ近くで再作成してみましょう。ただし、すべての単語の最初の文字のみを変更します。
mb_convert_case
実装の関連部分は次のとおりです。
int mode = 0;
for (i = 0; i < unicode_len; i+=4) {
int res = php_unicode_is_prop(
BE_ARY_TO_UINT32(&unicode_ptr[i]),
UC_MN|UC_ME|UC_CF|UC_LM|UC_SK|UC_LU|UC_LL|UC_LT|UC_PO|UC_OS, 0);
if (mode) {
if (res) {
UINT32_TO_BE_ARY(&unicode_ptr[i],
php_unicode_tolower(BE_ARY_TO_UINT32(&unicode_ptr[i]),
_src_encoding TSRMLS_CC));
} else {
mode = 0;
}
} else {
if (res) {
mode = 1;
UINT32_TO_BE_ARY(&unicode_ptr[i],
php_unicode_totitle(BE_ARY_TO_UINT32(&unicode_ptr[i]),
_src_encoding TSRMLS_CC));
}
}
}
基本的に、これは次のことを行います。
mode
し0
ます。mode
単語の最初の文字にいるかどうかを判断します。もしそうなら0
、そうでなければ、そうではありません。res
します。1
具体的に1
は、プロパティが「Mark、Non-Spacing」、「Mark、Enclosing」、「Other、Format」、「Letter、Modifier」、「Symbol、Modifier」、「Letter、Uppercase」、「文字、小文字」、「文字、タイトルケース」、「句読点、その他」または「その他、代理」。奇妙なことに、「手紙、その他」は含まれていません。mode
します。0
mbstring拡張子は、文字のプロパティを公開していないようです。mb_convert_case
これは問題を残します。なぜなら、キャラクターがテスト対象の10個のプロパティのいずれかを持っているかどうかを判断する良い方法がないからです。
幸い、正規表現のUnicode文字プロパティはここで私たちを救うことができます。
mb_convert_case
問題のある小文字への変換なしでの忠実な複製は次のようになります。
function mb_convert_case_utf8_variation($s) {
$arr = preg_split("//u", $s, -1, PREG_SPLIT_NO_EMPTY);
$result = "";
$mode = false;
foreach ($arr as $char) {
$res = preg_match(
'/\\p{Mn}|\\p{Me}|\\p{Cf}|\\p{Lm}|\\p{Sk}|\\p{Lu}|\\p{Ll}|'.
'\\p{Lt}|\\p{Sk}|\\p{Cs}/u', $char) == 1;
if ($mode) {
if (!$res)
$mode = false;
}
elseif ($res) {
$mode = true;
$char = mb_convert_case($char, MB_CASE_TITLE, "UTF-8");
}
$result .= $char;
}
return $result;
}
テスト:
echo mb_convert_case_utf8_variation("HETÁ1200 Ááxt ítring uii");
与える:
HETÁ1200ÁáxtÍtringUii