Perl の正規表現
Posted on Tue 07 January 2014 in blog
マッチ演算子
評価の結果は真偽値としては、マッチすれば真、そうでなければ偽。 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]
- char1 の char2 の間に入る任意の文字にマッチ
- char1, char2 を含む。
$&
- 最後にマッチした内容を保持
- 'Foo' =~ /^[A-Z]/ なら $& は F
\
- メタキャラクタに使ったり、エスケープに使う
\b
- 単語の区切りにマッチする
- 'abc def' にマッチさせたいときに、'Zabc def' にマッチしないよう、'babc def' と書いておく。
- アルファベットは、単語構成文字クラスなので、スペースや!は、b にマッチするが、Zはマッチしない。
\n
- ニューライン
\r
- キャリッジリターン文字
- カーソルを行頭に戻す
\t
- タブ
\f
- フォームフィード
- 改ページ
\e
- エスケープ文字
\NNN
- 8進数が NNN となる文字
- 例えば、040 はスペース
備考
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 にマッチしたものをその結果で置き換える。
|
その他の構文
選択、グループ化、キャプチャ、後方参照 | |
---|---|
構文 | 説明 |
X|Y|Z | 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つ方法がある。
コマンドラインオプション -a (と合わせて、-F)を使う
自分で各フィールドを変数に代入する
フィールドアクセス 構文 コメント ($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 |