正規表現で文字列のパターンマッチングするには (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つ目以降としてそれらの部分を返す。