マルチバイト文字列から重複した文字を除去するためのPHPメソッド?
-
29-10-2019 - |
質問
アーッッッッッッッッッッPHP count_chars(string string,3)コマンドに相当するマルチバイト文字の関数を作成する方法を知っている人はいますか?
それぞれの一意の文字の1つのインスタンスのみのリストを返すようにします。それは英語だったと私たちが持っていた場合
"aaabggxxxzxxgggghq xcccxxxzxxxyx"
それは"abgh qxyz"を返します(スペースがカウントされていることに注意してください)。
(この場合、順序は重要ではなく、何でもかまいません)。
日本の漢字なら(:
漢漢漢字漢字私私字私字漢字私漢字漢字私
そして、それは使用された3つの漢字だけを返します:
漢字私
UTF-8でエンコードされた文字列で動作する必要があります。
解決
こんにちはDaveいない これは... 一人が来る。
php > $kanji = '漢漢漢字漢字私私字私字漢字私漢字漢字私';
php > $not_kanji = 'aaabcccbbc';
php > $pattern = '/(.)\1+/u';
php > echo preg_replace($pattern, '$1', $kanji);
漢字漢字私字私字漢字私漢字漢字私
php > echo preg_replace($pattern, '$1', $not_kanji);
abcbc
何、あなたは私が使用するつもりだったと思った mb_substr
また?
Regex-speakでは、任意の1つの文字を探してから、同じ文字の1つ以上のインスタンスを探しています。その後、一致した領域は、一致した文字に置き換えられます。
ザ- u
モディファイア PCREでUTF-8モードをオンにします。 UTF-8シーケンス 8ビット文字の代わりに。処理されている文字列がすでにUTF-8である限り と PCREはUnicodeサポートでコンパイルされましたが、これは正常に動作するはずです。
こんにちは、私はなんと!
$not_kanji = 'aaabbbbcdddbbbbccgggcdddeeedddaaaffff';
$l = mb_strlen($not_kanji);
$unique = array();
for($i = 0; $i < $l; $i++) {
$char = mb_substr($not_kanji, $i, 1);
if(!array_key_exists($char, $unique))
$unique[$char] = 0;
$unique[$char]++;
}
echo join('', array_keys($unique));
これは、シャッフルコードと同じ一般的なトリックを使用します。文字列の長さを取得してから、次のようにします mb_substr
それを一度に一つの文字を抽出する。次に、その文字を配列のキーとして使用します。私たちはPHPの位置配列を利用しています:キーは、定義された順序でソートされます。文字列を調べてすべての文字を特定したら、キーを取得して、文字列に表示されたのと同じ順序で一緒に結合します。また、この手法から文字単位の文字数を取得します。
次のようなことがあれば、これははるかに簡単だったでしょう mb_str_split
と一緒に行くために str_split
.
(ここでは漢字の例はありませんが、コピー/貼り付けのバグが発生しています。)
ここでは、サイズのためにこれを試してみてください:
function mb_count_chars_kinda($input) {
$l = mb_strlen($input);
$unique = array();
for($i = 0; $i < $l; $i++) {
$char = mb_substr($input, $i, 1);
if(!array_key_exists($char, $unique))
$unique[$char] = 0;
$unique[$char]++;
}
return $unique;
}
function mb_string_chars_diff($one, $two) {
$left = array_keys(mb_count_chars_kinda($one));
$right = array_keys(mb_count_chars_kinda($two));
return array_diff($left, $right);
}
print_r(mb_string_chars_diff('aabbccddeeffgg', 'abcde'));
/* =>
Array
(
[5] => f
[6] => g
)
*/
あなたはこれを呼び出したいと思うでしょう 二度, 、右に左の文字列、左に右の文字列を持つ二度目。出力は異なります -- array_diff
ちょうどあなたに右から欠けている左側のものを与えるので、あなたは全体の話を得るために二度それをしなければなりません。
他のヒント
iconv_strlen PHP標準ライブラリ関数を確認してください。。オリエントエンコーディングについては言えませんが、ヨーロッパおよび東ヨーロッパの言語では問題なく機能します。いずれにせよ、それはいくらかの自由を与えます!
はるかに簡単です。str_splitを使用して、各文字を要素として持つフレーズを配列に変換します。次に、array_uniqueを使用して重複を削除します。ものすごく単純。複雑なことは何もありません。私はそれが好きです。