今回は毎度なにかと苦労させられる、正規表現についての備忘メモ。

日本語のようなマルチバイトの文字列を扱う場合、単純に$str[$i]のようにして一文字ずつ処理をしようと思うと文字がとれませんでした。
マルチバイトの文字列を一文字ずつ分割するには正規表現のpreg_splitを使うと良いみたいです。

やろうとしたこと

正規表現はまぁいろいろな場面で使えて便利ですが、PHPには基本のパターンマッチメソッドはけっこうあります。htmlのタグを除去したいであるとか、メールアドレスパターンを調べて、e-mailに使用できない文字を除去するであるとか。そういったことであれば、PHPに備わっているフィルタを使ったほうが良いと思います。(PHP:フィルタの型

今回はとある文字列をtwitterのハッシュタグになりうる文字列に変換したいなぁということで、特殊文字をはじくフィルタが必要でした。
全角の特殊文字フィルタくらいそこらへんに情報がありそうなものなのですが、正規表現は「完全」をめざすとなかなか深みにハマってしまう闇のようで、なかなかこれといった情報がありませんでした。

本記事では、「自分が使いたい文字を限定して、それ以外の文字についてはすべて除去する」という仕様にそった形になっています。
全然万能ではないですが、特殊文字をざっくりはじきたい人には使えるんじゃないでしょうか。

ちなみに、twitterのハッシュタグ用というより自分のアプリ内で有効な文字列でパターンを定義しているのでこのサンプルを使うと削除されたくない文字まで削除されてしまう可能性が高いのでご注意ください^^;

使用した関数

preg_split 正規表現で文字列を分割する
preg_match 正規表現によるマッチングを行う

概要とソースコード

使用可能な(除去しない)文字コードの正規表現パターンを定義して、一文字ずつパターンと照合して、パターンに含まれない文字を削除します。
※utf-8前提。他の文字コードでは動きません。

// 正規表現パターンを定義
$pattern = '/[0-9A-Za-zÀ-ÖØ-öø-žΑ-ёΑ-ω0-9A-Za-zぁ-ゖァ-ヾ一-鶴]/u';

// 特殊文字を除去したい文字列
$targetStr = 'utf-8の、日本語文字列。'

// 除去後の文字列を格納する変数
$resultStr = '';

// マルチバイト文字列を一文字ずつ分割した配列にする
foreach (preg_split('//u', $targetStr, -1, PREG_SPLIT_NO_EMPTY) as $targetChar) {
  $changePlace = preg_match($pattern, $targetChar);
  if($changePlace) $resultStr .= $targetChar;
}

echo $resultStr; // 出力:utf8の日本語文字列

このサンプルでは、ざっっっくりですが「半角英数字、全角英数字、ひらがな、漢字(日本語の)」以外の文字と、表記上たまにでてくるギリシャ文字とドイツ文字?とO(オー)の上に点々がついてる文字とかそのあたりが許可されます。

許可したい文字があれば、$patternに追加してください。
utf-8の文字コード表はこちらがみやすかったです。
UTF-8コード表(1) – 弘前学院聖愛中学高等学校

おわり