Perl の正規表現

Posted by ひつまぶし食べたい on Tuesday, January 7, 2014

マッチ演算子

評価の結果は真偽値としては、マッチすれば真、そうでなければ偽。 and, or, ! が役立つのは間違いない。

$_ にマッチさせる

/regex/
m:regex:

string にマッチさせる

string =~ /regex/
string =~ m:regex:

$_ の文字列置換

s/regex/new/
s:regex:new:

string の文字列置換

string =~ s/regex/new/
string =~ s:regex:new:

特殊なメタキャラクタ

^, $

  • 行頭、末尾にマッチ

.

  • ニューライン以外の任意の文字にマッチ

[chars]

  • chars に含まれる任意の1文字にマッチ
  • chars 内のバックスラッシュ付き英数字以外のメタキャラクタは、リテラル扱い

[^ chars]

  • chars に含まれない任意の1文字にマッチ
  • メタキャラクタの扱いは [chars] と同様

[char1-char2]

  • char1char2 の間に入る任意の文字にマッチ
  • char1, char2 を含む。

$&

  • 最後にマッチした内容を保持
  • 'Foo' =~ /^[A-Z]/ なら $& は F

\

  • メタキャラクタに使ったり、エスケープに使う

\b

  • 単語の区切りにマッチする
  • 'abc def' にマッチさせたいときに、'Zabc def' にマッチしないよう、'babc def' と書いておく。
  • アルファベットは、単語構成文字クラスなので、スペースや!は、b にマッチするが、Zはマッチしない。

\n

  • ニューライン

\r

  • キャリッジリターン文字
  • カーソルを行頭に戻す

\t

  • タブ

\f

  • フォームフィード
  • 改ページ

\e

  • エスケープ文字

\NNN

  • 8進数が NNN となる文字
  • 例えば、040 はスペース

::: note ::: title Note :::

8進数や16進数を調べるには、man ascii :::

\xNN

  • 16進数が NN となる文字
  • 例えば、x20 はスペース

\cX

  • X によって表される制御文字
  • 例えば、 cC はCtrl-C

\Q, \E

  • メタキャラクタを文字として見せたい部分を、\Q ... \E で囲む

POSIX の文字クラスとショートカットメタキャラクタ


文字クラス ショートカットメタキャラクタ 説明


[a-zA-Z0-9_] \w 単語構成文字

[^a-zA-Z0-9_] \W 非単語構成文字

[\040\t\r\n\cJ\cL] \s 空白文字

[^\040\t\r\n\cJ\cL] \S 非空白文字

[0-9] \d 数字

[^0-9] \D 数字以外の文字

マッチ修飾子

/RE/i や m%RE%xs, s/RE/new/e など、最後に修飾子をいくつかつけて、マッチングの動作を変更させることができる。

+———————————————————————-+ | マッチ修飾子 | +======================================================================+ | 修飾子 説明 | +———————————————————————-+ | =============== ==================================================== | +———————————————————————-+ | i | 大文字小文字の違いを無視 | +———————————————————————-+ | x | 拡張モード | +———————————————————————-+ | > | REフィールドに空白文字とコメントを許す | +———————————————————————-+ | s | シングルラインモード | +———————————————————————-+ | > | . をニューラインにもマッチさせる | +———————————————————————-+ | m | マルチラインモード | +———————————————————————-+ | > | ^, $ | | > を文字列の絶対的 | | な先頭、末尾でなく、ターゲット文字列中の行の先頭、末尾にマッチさせる | +———————————————————————-+ | g | | | すべてのマッチを、スカラーコ | | ンテキストかリストコンテキストかによって、連続的もしくは集合的に返す | +———————————————————————-+ | e | 置換の時に使う。 new を Perl のコードとして評価して、*RE* | | にマッチしたものをその結果で置き換える。 | +———————————————————————-+

その他の構文

+———————————————————————+ | 選択、グループ化、キャプチャ、後方参照 | +=====================================================================+ | 構文 説明 | +———————————————————————+ | ===================== ============================================= | +———————————————————————+ | XZ | X, Y, Zのいずれかにまっち | +———————————————————————+ | (X) | グループ化とキャプチャ | +———————————————————————+ | > | a(X|Y)bc や (XY)+ といった感じで使う | +———————————————————————+ | \1, \2, ... | 後方参照。検索文字列フィールドで使用 | +———————————————————————+ | $1, $2, ... | 後方参照。検索文字列フィールド以外で使用 | +———————————————————————+

量指定子

+———————————————————————-+ | 量指定子 | +======================================================================+ | 構文 説明 | +———————————————————————-+ | ====================== ============================================= | +———————————————————————-+ | X* | 0回以上の繰り返し | +———————————————————————-+ | X+ | 1回以上の繰り返し | +———————————————————————-+ | X? | 0 または 1回の出現 | +———————————————————————-+ | X{min, max} | min回以上max回以下の繰り返し | +———————————————————————-+ | X{min, } | min回以上の繰り返し | +———————————————————————-+ | X{count} | count回の繰り返し | +———————————————————————-+ | X{, max} | max回以下の繰り返し | +———————————————————————-+ | REP? | 量指定子の直後に ? をつけると、最短マッチ | +———————————————————————-+ | > | 例えば、.*? という風な。 | +———————————————————————-+

以下は、Perl で正規表現を扱うときのコツ

grep

grep -v

  • | perl で grep -v のように、マッチしないものを表示させるのは、次のように行う。

    # 空行以外を表示
    perl -wnl -e '/^$/ or print;' file
    

    | このように or を使うと便利。

grep -l

# foo にマッチするもののファイル名を表示
# close することで、マッチした後は探索しない。
perl -wnl -e '/\bfoo\b/ and print $ARGV and close ARGV;' file

カスケードフィルタ

  • シェルで grep "regex1" file | grep "regex2" とやることに相当

    # foo という単語と bar という単語を含む行を見つける
    perl -wnl -e '/\bfoo\b/ and /\bbar\b/ and print;' file
    

コンテキスト表示

  • 段落モード -00 と ファイルモード -0777 を上手く使う

  • /regex/s も上手く使うと良い

  • 行をまたがるマッチングを行うとき、間にどんな文字を許すか考える必要がある。ニューラインについて言えば、

    • マッチ修飾子の s を使って . をニューラインにマッチさせる
    • [\t\n]+ や [_\s]+ というように、明示的に指定したり、[^aiueo]+ などを使う
    • s を使う

sed

置換のデリミタ

  • 対応する括弧も使用可能

    s/.../.../
    s|...|...|
    s{...}{...}, s(...)(...)
    

行指定置換, コンテキストアドレス

  • sed では、次のように、置換の構文の前に、アドレスを指定して、置換する場所を制限できる。

    # 2行目のみ置換
    2s/regex/new/g
    # 2〜5行目のみ置換
    2,5s/regex/new/g
    # 行頭が fff の行について置換
    /^fff/s/regex/new/g
    
  • これを Perl では、行数に関する条件式で書く必要がある

    # 2行目のみ置換
    perl -wpl -e '$. == 2 and s/regex/new/g;' file
    # 2〜5行目のみ置換
    perl -wpl -e '2 <= $. and $. <= 5 and s/regex/new/g;' file
    # 行頭が fff の行について置換
    perl -wpl -e '/^fff/ and s/regex/new/g;' file
    

後方参照

  • sed では、キャプチャするときに、 ? を使えなかった。 Perl では、? を使える。

  • sed では、どこでも 1, 2, ...で参照したが、Perlでは 1, 2, ... と $1, $2, ... とどこから参照するかによって異なる。

    # Mr か Mr. を見る
    perl -wnl -e 's/(Mr.?) (Fo[oa])/$1 Bar $2/g;' file
    

計算結果で置換

  • sed では、置換文字列フィールドに計算結果を入れることが難しかった。(できるか知らない。)

  • perl では、簡単にできる。マッチ修飾子の e が必要。

    perl -wnl -e 's/\d+/$& * 2.1/ge;' file
    

AWK

フィールドアクセス

  • AWK では、フィールドアクセスが便利

    # スペースorタブ区切りのフィールドの順番を入れ替える
    awk '{ print $2, $1}' file
    
  • Perl で似たようなことをやるには、2つ方法がある。

    1. コマンドラインオプション -a (と合わせて、-F)を使う

    2. 自分で各フィールドを変数に代入する

      フィールドアクセス

      構文 コメント ===================== ============================== ($A, $B)=@F; それぞれの変数にセット ($A, undef, $B)=@F; 第2フィールドは変数に入れない $numfields=@F; レコードのフィールド数を格納

パターン範囲

+———————————————————————-+ | パターン範囲 | +======================================================================+ | 演算子 構文 コメント | +———————————————————————-+ | ========= ================== | | = | | ==================================================================== | +———————————————————————-+ | .. regex1 .. regex2 | | | regex1を含む最初のレコードからregex2を含む最初のレコードまでの範囲 | +———————————————————————-+ | > | 一旦regex1とregex2の組が見つかると次のregex1を見つけるまで、無視 | +———————————————————————-+ | > | regex1とregex2が同じレコードにある場合もマッチ。 | +———————————————————————-+ | ... regex1 ... regex2 | .. とほぼ同じ。 | +———————————————————————-+ | > | ただし、regex2はregex1の次の行以降から探す。 | +———————————————————————-+

find

ファイル属性テスト

ファイル属性テスト (○ は属性に対応する文字)

構文 コメント ====================== ========================================================= -○ filename filename が○という属性を有していることをテスト ! -○ filename filename が○という属性を有していないことをテスト -○ $_ が○という属性を有していることをテスト ! -○ $_ が○という属性を有していないことをテスト

ファイル属性と対応する演算子

ファイル属性 演算子 ===================================== ========================================================= 通常ファイル -f ディレクトリ -d シンボリックリンク -l 名前付きパイプ -p キャラクタ -c ブロック -b ソケット -S 空 -z 空でない -s ------------------------------------- --------------------------------------------------------- 実UID/GIDで読取り可 -R 実UID/GIDで書込み可 -W 実UID/GIDで実行可 -X 実UIDが所有 -O 実効UID/GIDで読取り可 -r 実効UID/GIDで書込み可 -w 実効UID/GIDで実行可 -x 実効UIDが所有 -o 指定のUID/GIDが所有 stat ------------------------------------- --------------------------------------------------------- setuid -u setgid -g sticky -k テキスト -T バイナリ -B ------------------------------------- --------------------------------------------------------- 別のファイルより新しい stat 別のファイルより後にアクセスされた stat リンクの数 stat inode番号 stat


comments powered by Disqus