今回も文字列検索では定番のgrepです。今回は日本語等での検索を行ってみます。
前回同様にデスクトップのsampleディレクトリにサンプルとなるテキストファイルを入れておきます。また、カレントディレクトリはsampleディレクトリとします。コマンドならcd ~/Desktop/sampleと入力します。
macOSへの対処
macOSの場合、デフォルトでインストールされているgrepでは手軽に日本語や漢字など様々な文字にマッチさせるのが大変(面倒)です。そこでHomebrewを使ってGNU版のgrepをインストールして使うのがよいでしょう。なお、インストールするとコマンド名はgrepでなくggrepになります。以下の説明でgrepのコマンド名をggrepに置き換えて実行してください。
Homebrewをインストールしていない場合は以下のURLにアクセスしてインストールしてください。
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
以下のようにしてGNU版のgrepをインストールします。
brew install grep
以下のコマンドを入力してインストールされたか確認します。この場合、バージョンが表示されます。
ggrep -V
日本語にマッチ
それでは日本語にマッチする処理をやってみましょう。ここまでは英語でマッチする例ばかりでした。こういう正規表現のマッチパターン例では、ほとんどが英語になるのも仕方ないのかもしれません。英語圏の文字は基本的に1バイトで表現されますが、日本語や中国語などは2バイト以上のマルチバイトで表現されます。おまけに日本語などマルチバイトでは文字をどのように示すかのコードが複数あります。日本語なら過去にはJIS、一番多く使用されていたShift JIS、そしてUNIX系で使われていたEUCがあります。今は文字コードが複数混雑していた時代からUnicodeに統一されました。が、Unicodeもなかなか複雑です。とは言え絵文字の普及にともなって、かなり改善されたはずなので、ここからは日本語のマッチについてトライしてみましょう。また、仮名と濁点は分離されていないものとします。(NFC(Normalization Form Canonical Composition)の状態とします)
また、2000年より前のテキストの場合、文字コードはShift JISやEUCの可能性があります。そのようなテキストデータを扱う場合はnkf,iconvなどで文字コードをUnicodeに変換してからgrepでマッチさせる方がよいでしょう。
日本語1文字/絵文字にマッチ
まず簡単なところで日本語/絵文字の1文字だけにマッチさせてみましょう。ここで使用するテキストファイル(sample1.txt)の内容は以下のようになっています。
sample1.txt
Sample Text (Alphabet only)
この行は平仮名と漢字とカタカナが混在しています。
ここは、ひらがなのみです
ココハカタカナダケ
〜やーなどの記号です
漢字文化圏
😀😀😀😀
이 문장은 한글 문자로 쓰여 있습니다.
هذه الجملة مكتوبة باللغة العربية.
「す」の1文字にマッチするには以下のように指定します。
grep 'す' sample1.txt
マッチする文字がない場合は何も出力されません。
grep 'ん' sample1.txt
絵文字にマッチさせるのも同様に指定できます。
grep '😀' sample1.txt
単純な日本語文字列にマッチ
次に日本語文字列にマッチさせてみましょう。ここでは、文章中に含まれる「です。」の文字にマッチさせます。この場合は単純にgrepの文字列として指定するだけです。ここらへんは英文字の場合と変わりません。それぞれのテキストファイルの内容は以下のようになっています。
sample2a.txt
今日はいい天気ですね。
明日も晴れです。
明後日は雨の予報。
sample2b.txt
今日はいい天気だ。
明日は晴れだ。
明後日は雨の予報である。
ここで「です。」にマッチさせる場合は以下のようになります。ですます調から断定調になっているかどうか確認する場合に使えます。
grep 'です。' sample2a.txt
grep 'です。' sample2b.txt
平仮名/片仮名だけでなく漢字にもマッチできます。
grep '天気' sample2a.txt
明日や明後日のように明と日で囲まれた文字(範囲内は漢字)にマッチさせる場合は以下のようになります。
grep -P '明[一-龯]*日' sample2a.txt
平仮名にマッチ
次に平仮名にマッチさせてみましょう。平仮名は以下のように指定します。
grep -P '\p{Hiragana}' sample1.txt
ただし、この指定方法だと句読点などにもマッチしてしまいます。句読点は除外したい場合は以下のように指定します。
grep -P '(?![・ー、。ー〜])\p{Hiragana}' sample1.txt
片仮名にマッチ
次に片仮名にマッチさせてみましょう。片仮名は以下のように指定します。
grep -P '\p{Katakana}' sample1.txt
ただし、この指定方法だと句読点などにもマッチしてしまいます。句読点は除外したい場合は以下のように指定します。
grep -P '(?![・ー、。ー〜])\p{Katakana}' sample1.txt
漢字にマッチ
次に漢字にマッチさせてみましょう。漢字は以下のように指定します。なお、ここでの漢字は日本語圏での漢字だけでなく簡体字・繁体字なども含まれます。
grep -P '\p{Han}' sample1.txt
ただし、この指定方法だと句読点などにもマッチしてしまいます。句読点は除外したい場合は以下のように指定します。
grep -P '(?![・ー、。ー〜])\p{Han}' sample1.txt
ハングルにマッチ
ハングル文字にマッチさせたい場合は以下のように指定します。
grep -P '\p{Hangul}' sample1.txt
ただし、この指定方法だとなぜか日本語の句読点などにもマッチしてしまいます。句読点は除外したい場合は以下のように指定します。
grep -P '(?![・ー、。ー〜])\p{Hangul}' sample1.txt
各国語にマッチ
各国語にマッチする指定方法を以下に示します。
| 日本語 - ひらがな | \p{Hiragana} |
| 日本語 - カタカナ | \p{Katakana} |
| 日本語 - 漢字(CJK統合漢字) | \p{Han} |
| 韓国語 - ハングル | \p{Hangul} |
| 中国語 - 漢字(繁体字・簡体字) | \p{Han} |
| 英語(ラテン文字) | \p{Latin} |
| アラビア語 | \p{Arabic} |
| キリル文字(ロシア語など) | \p{Cyrillic} |
| ギリシャ文字 | \p{Greek} |
| ヘブライ文字 | \p{Hebrew} |
| タイ文字 | \p{Thai} |
| ベトナム語(ラテン系) | \p{Latin} |
| ヒンディー語(デーヴァナーガリー) | \p{Devanagari} |
| タミル語 | \p{Tamil} |
| ベンガル語 | \p{Bengali} |
| グルムキー語(パンジャーブ語) | \p{Gurmukhi} |
| テルグ語 | \p{Telugu} |
| カンナダ語 | \p{Kannada} |
| マラヤーラム語 | \p{Malayalam} |
例えばアラビア語にマッチさせたい場合は以下のように指定します。他にもいろいろ指定して試してみてください。
grep -P '\p{Arabic}' sample1.txt
grepは昨今のように多国語が入り乱れてくると、なかなか期待通りにマッチさせるのが難しくなってきます。そんな場合は、AIを使ってパターンマッチする部分を生成してもらえばよいでしょう。
それでは、また次回。























