正規表現で文字列のパターンマッチングするには (match / preg_match / search / =~)
2015/04/18
各プログラミング言語での、正規表現で文字列のパターンマッチングをする方法。文字列全体ではなく部分マッチング。
Java
if ("Hello, world!".matches(".*wor.*")) {
System.out.println("Match!");
}
Scala
if ("Hello, world!".matches(".*wor.*")) {
println("Match!");
}
if (preg_match("/wor/", "Hello, world!")) {
echo "Match!\n";
}
import re
if re.compile("wor").search("Hello, world!"):
print("Match!")
if "Hello, world!" =~ /wor/
puts("Match!")
end
if ("Hello, world!" =~ /wor/) {
print("Match!\n");
}
if [[ "Hello, world!" =~ "wor" ]]; then
echo OK
fi
if ("Hello, world!".match(/wor/)) {
console.log("Match!");
}
関連
PHP 2016/06/03
preg_match という関数は、正規表現にマッチしたら 1, マッチしなかったら 0 が返される。正規表現が間違っているなどのエラーの際は false が返される。
preg_match("/a./", "abc\nabc"); // => 1
preg_match("/x./", "abc\nabc"); // => 0
preg_match("/a", "abc\nabc"); // => false
PHPでは 0 は if の条件の中に入れたら false とみなされるので、ifの条件式の中に素直に書ける。
(-> 論理値への変換)
if (preg_match("/x./", "abc\nabc")) { // NG
...;
}
preg_match は文字列全体のマッチングではなく、部分マッチングであるので、全体のマッチングをしたいのであれば、正規表現の '\A', '\z' を使うとよい。
正規表現はバックスラッシュを多用するので、"" ではなく '' で囲んだほうが便利。
"" で囲む場合は、"\\A", "\\z" などとバックスラッシュをたくさん書く必要がある。
preg_match('/bc/', "abc\nabc"); // => 1
preg_match('/\Abc\z/', "abc\nabc"); // => 0
パターン自体に / を使いたい場合、 \/ というふうにエスケープを使う必要がある。ファイルパスのパターンマッチングなどで、パターン自体に / をたくさん書く場合、全部エスケープするのは面倒なので、その場合はパターンの先頭と最後を / 以外の、例えば ! とかにするとよい。
"!\A/var/log/httpd/.+_log\z!" みたいに。先頭と最後を / にすると、
"/\A\/var\/log\/httpd\/.+_log\z/" と書かないといけない。その代わり、先頭と最後を ! にした場合は、パターン自体に含まれる ! は \! と書かないといけない。
日本語などのマルチバイトの文字を扱うには正規表現に修飾子 u を使う。
if (preg_match('/\A[ぁ-ゖ]*\z/u', $str)) {
...;
}
3つ目の引数を渡すと、マッチした部分文字列を取得することができる。 -> 正規表現で文字列をキャプチャするには
preg_match 関数 | PHP Manual
http://php.net/manual/ja/function.preg-match.php
PCRE(Perlと互換性の高い正規表現)のパターン | PHP Manual
http://php.net/manual/ja/pcre.pattern.php
正規表現パターンに使用可能な修飾子 | PHP Manual
http://php.net/manual/ja/reference.pcre.pattern.modifiers.php
Python 2016/01/09
コンパイルした正規表現をオブジェクトとして保持して、そのオブジェクトの
matchメソッドなどを呼び出す。
import re
r = re.compile("bc")
print("match" if r.match("abc") else "unmatch") # => unmatch
r = re.compile("ab")
print("match" if r.match("abc") else "unmatch") # => match
matchメソッドは、文字列の先頭がマッチするかどうかであり、文字列全体のマッチングではなく、部分マッチングというわけでもない。
searchメソッドであれば、他の言語と同様に部分マッチングする。
match(str)- 文字列の先頭がマッチするかどうかを判定し、マッチしたら
MatchObjectインスタンスを返し、マッチしなかったらNoneを返す search(str)- 文字列の先頭に限らずマッチするかどうかを判定し、マッチしたら
MatchObjectインスタンスを返し、マッチしなかったらNoneを返す findall(str)- マッチする部分のすべてを
MatchObjectインスタンスのリストで返す。マッチしなければ空のリストを返す finditer(str)- マッチする部分すべてを
MatchObjectインスタンスのイテレータで返す。マッチしなければ空のイテレータを返す
正規表現 HOWTO | Python 2.7 documentation
http://docs.python.jp/2/howto/regex.html
正規表現 HOWTO | Python 3 documentation
http://docs.python.jp/3/howto/regex.html
Ruby / JRuby 2016/01/08
=~ という演算子は、正規表現にマッチしていたら、そのマッチした部分の先頭の文字のインデックスを返し、マッチしなければ nil を返す。
"abc\nabc\n" =~ /a./ # => 0
"abc\nabc\n" =~ /x./ # => nil
Rubyでは 0 も if の条件の中に入れたら true とみなされるので、ifの条件式として素直に使える。
(-> 論理値への変換)
if "abc\nabc\n" =~ /a./ # OK
...
end
文字列全体のマッチングではなく、部分マッチングであるので、全体のマッチングをしたいのであれば、正規表現の '\A', '\z' を使うとよい。
マッチングの後 $~ や $1, $2, $3 でマッチした部分文字列を取得することができる。
-> 正規表現で文字列をキャプチャするには
!~ という演算子は =~ の反対で、正規表現にマッチしていたら false を返し、マッチしなければ true を返す。インデックスは返さない。
/a./ !~ "abc\nabc\n" # => false
/x./ !~ "abc\nabc\n" # => true
Perl 2015/04/15
=~ という演算子で、正規表現にマッチしていれば '1' を返し、マッチしていなければ '' を返す。
print "abc\nabc\n" =~ /a./;
# => 1
print "abc\nabc\n" =~ /a$/;
# => なにも出力しない
!~ という演算子は =~ の反対で、マッチしていれば '' を返し、マッチしていなければ 1 を返す。
正規表現の中にカッコで囲んだグループがあれば、マッチした場合、
$1, $2, $3, … にマッチした文字列が入る。
-> 正規表現のグルーピングにマッチした文字列
if文の条件式の中に正規表現だけを書いた場合は、その前に $_ =~ を付けたのと同じになる。
正規表現は普通は / で囲むが、文字列として書くこともできる。
print "abc\nabc\n" =~ ('a' . '.');
# => 1
sh (シェルスクリプト) 2015/04/30
bashだと [[ というコマンドで =~ という演算子が使えて、正規表現でマッチングできる。
[[ "Hello, world!" =~ "wor" ]]
echo $?
# => 0
[[ "Hello, world!" =~ "unmatch" ]]
echo $?
# => 1
if文で使う例。
if [[ "Hello, world!" =~ "wor" ]]; then
echo OK
fi
zshでもできるみたい。Ubuntuにあるdashではできなかった。
次はシェルの機能を使わずに grep でする方法。
echo "Hello, world!" | grep "wor" >/dev/null
echo $?
# => 0
echo "Hello, world!" | grep "unmatch" >/dev/null
echo $?
# => 1
これをif文で使う例。
if echo "Hello, world!" | grep "wor" >/dev/null; then
echo OK
fi
JavaScript 2013/04/19
"abc\nabc\n".match(/a./); // => ["ab"]
"abc\nabc\n".match(/a(.)(.*)/); // => ["abc", "b", "c"]
マッチしない場合は null を返す。マッチした場合は最初にマッチした部分の文字列を配列で返す。パターンにカッコを使った部分があれば配列の2つ目以降としてそれらの部分を返す。