0
0

More than 3 years have passed since last update.

【PHP】文字化け文字を含むマルチバイト(全角スペース等)対応のtrim処理

Posted at

概要

PHPで全角のトリムを行う必要があった。ただトリムを行う文字列に文字化け文字が含まれていると 他の trimの記事の方法だときちんと動かなかった。

最初
https://qiita.com/fallout/items/a13cebb07015d421fde3
この記事を参考にして、全角トリムを行ってみたが、
' 町 いなぎ 'のような文字化け文字が含まれていると、
'福井 'が'福井'のように文字化け文字まで削除されてしまった。

自分で考えてみたが 美しく作れなかった

結局ループを回して全角と半角スペースを取り除いたが、きれいなコードを書けなかった。CsvUtilityというクラス名もイケてない。

CsvUtility.php


class CsvUtility {
    /**
     * 全角トリム 文字化け対応 (なんという醜いコードであろう)
     * @param string $trimString
     * @return string
     */
    public static function zenTrim(string $trimString)
    {
        // https://qiita.com/fallout/items/a13cebb07015d421fde3 ↓を参考にしました
        //return preg_replace('/\A[\p{C}\p{Z}]++|[\p{C}\p{Z}]++\z/u', '', $trimString); // '福井 'が'福井'になってしまう
        //return trim(mb_convert_kana($trimString, "s", 'UTF-8')); // 'あ い'が'あ い'になってしまう
        $spos = 0;
        for ($i = 0; $i < mb_strlen($trimString); $i++) {
            $ch = mb_substr($trimString, $i, 1);
            if ($ch != ' ' && $ch != ' ') {
                $spos = $i;
                break;
            }
        }
        if ($spos > 0) {
            $trimString = mb_substr($trimString, $spos);
        }

        $epos = 0;
        for ($i = 0; $i < mb_strlen($trimString); $i++) {
            $ch = mb_substr($trimString, mb_strlen($trimString) - $i - 1, 1);
            if ($ch != ' ' && $ch != ' ') {
                $epos = $i;
                break;
            }
        }
        if ($epos > 0) {
            $trimString = mb_substr($trimString, 0, mb_strlen($trimString) - $epos);
        }

        return $trimString;

    }
}


CsvUtilityTest.php

class CsvUtilityTest extends \Tests\TestCase
{
    /** @@test */
    public function 全角トリム動作確認()
    {
        $this->assertSame(CsvUtility::zenTrim('   北九州眞   '), '北九州眞');
        $this->assertSame(CsvUtility::zenTrim('   髙橋 未来虹   '), '髙橋 未来虹');
        $this->assertSame(CsvUtility::zenTrim('   ハリー・S・トルーマン   '), 'ハリー・S・トルーマン');
        $this->assertSame(CsvUtility::zenTrim(' a '), 'a');
        $this->assertSame(CsvUtility::zenTrim(' あ '), 'あ');
        $this->assertSame(CsvUtility::zenTrim(' あ い '), 'あ い');
        $this->assertSame(CsvUtility::zenTrim(' あ い '), 'あ い');
        $this->assertSame(CsvUtility::zenTrim('本多宏顕'), '本多宏顕');
        $this->assertSame(CsvUtility::zenTrim('   ハリー・S・トルーマン      '), 'ハリー・S・トルーマン');
        $this->assertSame(CsvUtility::zenTrim(' Harry S. Truman '), 'Harry S. Truman');
        $this->assertSame(CsvUtility::zenTrim('東京 東子          '), '東京 東子');
        $this->assertSame(CsvUtility::zenTrim('大阪            '), '大阪 ');
        $this->assertSame(CsvUtility::zenTrim('  町 いなぎ    '), '町 いなぎ');
        $this->assertSame(CsvUtility::zenTrim('りんだ ジェネヴィヴ    '), 'りんだ ジェネヴィヴ');
    }
}

グリーンビルドになったものの

Testing started at 6:54 ...
php ./vendor/phpunit/phpunit/phpunit --configuration ./phpunit.xml --filter "/(Tests\Service\csv\CsvUtilityTest::全角トリム動作確認)( .*)?$/" --test-suffix CsvUtilityTest.php ./tests/Service/csv --teamcity

PHPUnit 8.5.8 by Sebastian Bergmann and contributors.

Time: 490 ms, Memory: 24.00 MB

OK (1 test, 14 assertions)
Process finished with exit code 0

なんか釈然としない。

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0