Yamamoto's Laboratory
 
文字列操作
 
 
 
 

正規表現を使った処理

数値の処理に比べて,文字列の処理は格段に複雑です.文字列を取り扱いやすくするためには,その形式を表現する方法が必要です.正規表現(regular expression)は文字列の形式を表します.ここでは,正規表現とそれを使った処理を示します.

パターンマッチ

文字列の処理では,対象となる文字列のパターンが重要です.特定の文字が含まれるか含まれないか,任意の文字並びが含まれるか,特定の文字の後にある文字列が含まれるか — 等です.さまざまな文字列のパターンが考えられ,それらについて処理を行わなくてはなりません.その文字列のパターンは正規表現で表すことができます.

正規表現

ある任意の文字列と正規表現で表された文字列パターンとを比較することができます.それをパターンマッチと言います.以下の表にパターンマッチに使われる正規表現を示します.

パターンマッチに使われる正規表現
正規表現 文字列パターン
[abcXYZ] a,b,c,X,Y,Zのどれかひとつ
[a-z] a〜zのどれかひとつ
[C-W5-7] C〜W,あるいは5〜7のどれかひとつ
[^ab] 'a'と'b'以外にマッチ.ブラケット直後の ^ は否定
hoge | fuga hoge あるいは fuga のいずれか
. 改行文字(\n)以外の任意の1文字
\s\S \s は空白文字*1にマッチ.\Sはその否定.
\d\D \d は0〜9の数字にマッチ([0-9]と同じ).\D はその否定.
\w\W 英文字と英数字([a-zA-Z0-9])]にマッチ.\W はその否定.
* 直前の文字がゼロ個以上
+ 直前の文字が1個以上
? 直前の文字が0個または1個
{3,8} 直前の文字が3個以上,8個以下
{6} 直前の文字が6個
{7,} 直前の文字が7個以上
(パターン) 「\整数」で括弧内の文字列を参照できる*2
\b\B \b は単語境界,\B は単語境界ではない.
^ 直後が文字列の先頭
$ 直前が文字列の末尾
  • *1 空白文字とは,「スペース,CR, Tab, LF, 改ページ」のこと.
  • *2 /xx(.)yy([a-z])zz\2\1/は,「xx9yyazza9や「xxByykzzkB」にマッチする.\1は最初の括弧内の . に対応した文字列(ここでは文字),\2は次の括弧内の文字列になる.

注意事項

  • 制御に使われる文字を正規表現内で文字として使う場合には,エスケープ(文字の前に\をつける)しなくてはなりません.このような文字は,「\」や「*」,「+」,「.」,「?」,「{」と「}」,「(」と「)」,「[」と「]」,「^」,「|」,「\」です.また,「-」は各括弧[ ]内に書くときのみエスケープします.
  • 優先順位  演算子の優先順は,(1)括弧「()」,(2)繰り返しを表す「*,+,?,{3,8}」,(3)並び,位置指定,(4)または「|」です.このページに詳しく書いてある.

具体的な操作

文字列の操作に正規表現を使う場合,/正規表現/とスラッシュで囲む.最後に i を付けると大文字と小文字の違いを無視する(ignore case).

  • 比較  正規表現を使って,比較ができます.比較の結果は,真(TRUE)か偽(FALSE)です.
    if(/abc/){
        # $_に'abc'が含まれていれば,実行
    }
    
    if($hoge=~/xyz/){
        # $hogeに'xyz'が含まれていれば,実行
    }
    
    if($fuga=~/stu/i){
        # $fugaに,大文字でも小文字の違いを無視して'stu'が含まれていれば,実行
    }
    
  • 置換  s/元の文字列/新文字列/で文字列の置換ができます.
    • 最初にマッチした文字列のみを変換します.マッチする全てを変換する場合は,gオプションを付ける.
    • 大文字と小文字の違いを無視してマッチさせる場合,iオプションを付ける.
    s/old/new/;                     # $_中の'old'を'new'に置換
    $hoge =~ s/.txt$/.dat/;     # $hoge中の末尾の'.txt'を'.dat'に置換
    $fuga =~ s/(^.)/aaa $1/;   # $fugaの文字列の先頭に'aaa 'を追加
    $foo =~ s/ok/NG/i;           # 大文字,小文字の関係なく'ok'を'NG'に
    $bar =~ s/a/A/g;             # 全ての'a'を'A'に
    $aaa =~ s/god/Satan/ig;    # iとgオプションの両方を使う
    

よく使われる操作

私がよく使う正規表現の例を示します.

  • 拡張子削除  ファイル名から拡張子を取り除くときに,使います.最初の例は,$file_name から拡張子を取り除いています.二番目の例は,$file_name の拡張子を取り除いた部分を $file に代入しています($file_nameはそのまま).
    $file_name =~ s/^(.*)\..*$/$1/;              # $file_nameの拡張子を取り除く
    ($file = $file_name) =~ s/^(.*)\..*$/$1/;    # $file_nameの拡張子を取り除き,$file に代入
  • 拡張子取り出し  拡張子は,次のようにして取り出せます.$file_nameの拡張子を $ext に代入しています.
    ($ext=$file_name) =~ s/^.*\.(.*)$/$1/;
    
  • 前後の空白文字削除  ファイルからデータを読み込んだ場合に,前後に無駄な空白文字(スペース,CR, Tab, LF, 改ページ)がありがちです.次のようにして取り除くことができます.
    ($A = $text) =~ s/^\s*//;              # 前の空白を取り除く
    ($B = $text) =~ s/\s*$//;              # 後ろの空白を取り除く
    ($C = $text) =~ s/^\s*(.*?)\s*$/$1/;   # 前後の空白を取り除く
    

文字列の分割と結合

  • splitによる分割  文字列を分割する場合,split(デリミタ,文字列)を使うと簡単です.
    $sentence='To be or not to be, that is the question;';
    @word=split(/\s+|,\s*|;\s*/, $sentence);
    # $sentenceが単語に分けられて,@wordに格納
    # @word=('To','be','or','not','to','be','that','is','the','question')となる
    
    @test=split(/:/);         # この場合は,$_の文字列をコロンで分割
    
  • joinによる結合  配列に格納された文字を結合する場合,join(はさむ文字,配列)を使うと簡単です.
    @word=('If','winter','comes','can','spring','be','far','behind');
    $sentence=join(" ",@word);
    # $sentence='If winter comes can spring be far behind'となる.
    
  • .による結合  単純な結合の場合は,.(ピリオド)を使うと簡単です.
    $a='Time';
    $b='money';
    $capitalism=$a.' is '.$b.'.';
    # $capitalism='Time is money.'となる.
    

ページ作成情報

参考資料

  1. MASさんの「Perlで書く」は,大変よく書かれています.特に,「Perl表技集」は,プログラミングの参考になります.

更新履歴

2005年頃


no counter