1. ホーム
  2. スクリプト・コラム
  3. ルビートピックス

文字列のマッチングと置換のためのRuby正規表現

2022-01-31 12:22:15

レギュラーマッチング

Rubyといえば、もちろん正規表現の仕組みにも触れなければならない。正規表現は、文字列の検証やマッチングからWeb抽出まで、さまざまな領域で強力なマッチング言語として使われるようになってきている。正規表現によるマッチングの効率性を批判する声もあるが、正規表現の威力を考えれば問題ないだろう。

Rubyの正規表現は、Rubyの=~とmatchを抜きにしては語れません。そこで、この2種類のマッチングの違いを例で説明しましょう。まず、=~の使い方について。

message="afhadhffkdf414j" 
regex=/[a-z](\d{3})[a-z]/ 
puts regex=~message 
message="afhadhffkdf414j" 
regex=/[a-z](\d{3})[a-z]/ 
puts regex=~message 


Rubyでは、正規表現のマッチング文を表すのに、//が使われます。これを実行すると、上の文は両側に小文字のついた3つの数字の文字列にマッチします。なぜ結果が10になるのか、不思議に思うだろう。これが =~ の美点で、マッチした最初の出現箇所を出力するのです。

では、matchを見てみましょう。

message="afhadhffkdf414j" 
regex=/[a-z](\d{3})[a-z]/ 
puts regex.match(message) 
 
message="afhadhffkdf414j" 
regex=/[a-z](\d{3})[a-z]/ 
 
puts regex.match(message) 


出力を見てみましょう。f414jは、ルールにマッチするすべての正規文の集合を表す文字列です。お気づきかどうかわかりませんが、正規表現では括弧を使用しており、その中から3桁の数字を抜き出したいと思います。もちろん、これも非常に簡単で、上のコードを少し変更するだけでいい。

message="afhadhffkdf414j" 
regex=/[a-z](\d{3})[a-z]/ 
regex.match(message) 
puts $1 
 
message="afhadhffkdf414j" 
regex=/[a-z](\d{3})[a-z]/ 
regex.match(message) 
puts $1 


結果は当然414です。なぜ$0でなく$1を使うのか?0の場合はどうなるのか見てみましょう。

C:/Users/Administrator/Documents/NetBeansProjects/RubyApplication1/lib/regex.rb



このオブジェクトの出力情報である。

ここで新しい状況を紹介します。文字列の中にたくさんのマッチがある場合はどうでしょう。上の文は最初に見つかった結果にのみマッチし、すべての結果を表示する必要があります。最初はjavaの影響を受けて、matchの結果は集合になると思っていたので、全体をどうするかは考えていませんでした。そこで見つけたのがscanメソッドです。そのコードを以下に示す。

message="afhadhffkdf414j9tr3j43i3433094jwoert223jwew123dfdf" 
regex=/[a-z](\d{3})[a-z]/ 
message.scan(regex).each{|m|puts"Theresultis#{m[0]}"} 
 
message="afhadhffkdf414j9tr3j43i3433094jwoert223jwew123dfdf" 
regex=/[a-z](\d{3})[a-z]/ 
message.scan(regex).each{|m|puts"Theresultis#{m[0]}"} 


端的に言えば、その結果です。

Theresultis414 
Theresultis223 
Theresultis123 
 
Theresultis414 
Theresultis223 
Theresultis123 


どうです、便利でしょう。マッチしたものをすべて抽出するのは簡単です。

正規表現のグループ化

正規表現をグループ化し、マッチングに成功した後にグループ化した値を$1,$2,$3,$4に格納することができる ......................。

print $1,"\n",$2 if "a1b2c3d4e5" =~ /(\w{2})(\w*)/ 



文字列の定期的な置き換え。

print "abcd".sub(/\w/,"9") 
print "\n"  
print "abcd".gsub(/\w/,"9") 




レギュラーで特殊なグローバル変数。

  •     $1,$2,$3 .... グループ化されたマッチングテキスト
  •     $` 前のテキストに一致させる
  •     $' はテキストの後にあるテキストにマッチします
print <pre name="code" class="ruby">,"\n",{1},"\n", 

if "ab9cd" =~ /\d/