12
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Regexp】正規表現まとめ(基礎)[Ruby編]

Last updated at Posted at 2018-07-10

前書き

正規表現を使いこなせるようになるために、ここに整理してまとめておきます。他の方にも参考になれば幸いです。

正規表現オブジェクトの作り方

1. パターンを「/ /」で囲む

例) /R..y/
これは「Rから始まってyで終わる、4文字の文字列」

2. クラスメソッドからオブジェクトを作る

例) reg = Regexp.new("Ruby")
「Ruby」という文字列を元に作成

3. %rを使用する

例) %r!パターン!
正規表現中に「/」を使いたいときに便利
**注)**他にも「%r<パターン>」のような表現方法もありますので、お好みに応じて選択ください。ただ、主観ですが、linuxで正規表現を扱うとき、「!」が好まれて使われている印象があります。

マッチング

正規表現 =~ 文字列
「=~」 は、正規表現と文字列がマッチングするか調べるためのメソッド。

irb(main):001:0> /ruby/ =~ "ruby"
=> 0
irb(main):002:0> /uby/ =~ "ruby"
=> 1

マッチングした場合は、何番目の文字にマッチしたかを返します。ただし、0から始まる点に注意です。

####行頭と行末にマッチ
「^」:行頭とマッチするパターン
「$」:行末とマッチするパターン

irb(main):003:0> /^ruby$/ =~ "ruby"
=> 0
irb(main):004:0> /^ruby/ =~ "rubyruby"
=> 0
irb(main):005:0> /ruby$/ =~ "rubyruby"
=> 4
irb(main):006:0> /^ruby$/ =~ "rubyruby"
=> nil

注)「行頭・行末」は「文字列の先頭・末尾」ではありません!
つまり、次の「/^ruby$/」というパターンは「"hoge\nruby"」という文字列に一致します。
先程の最後の例ではnilが返ってきていますが、次の例ではマッチし数字が返ってきます。

irb(main):007:0> /^ruby$/ =~ "hoge\nruby"
=> 5

次に、「文字列の先頭・末尾」の例を示します。

####文字列の先頭と末尾にマッチ
「\A」:文字列の先頭とマッチするパターン
「\z」:文字列の末尾でマッチするパターン

irb(main):008:0> /\Aruby\z/ =~ "hoge\nruby"
=> nil

上記の理由からこちらは一致しません。

####マッチさせたい文字を範囲で指定

  • [abc] :aまたはbまたはc
  • [012abc]:0、1、2、a、b、cのどれかの文字

「-」を使うことで範囲内の文字全てを指定できる

  • [a-z] :aからzまでの、アルファベットの小文字全部
  • [A-Z] :AからZまでの、アルファベットの大文字全部
  • [0-9] :0から9までの、数字全部
  • [A-Za-z] :AからZまでとaからzまでのアルファベット全部
  • [A-Za-z_] :アルファベット全部と「_」

注)「-」を単なる文字として表したいときは、最初か最後に書く

  • [A-Za-z0-9_-] :アルファベットと数字全部と「_」と「-」

####任意の文字とマッチ

  • 「.」 :任意の1文字とマッチ

####バックスラッシュを使ったパターン

  • 「\s」 :空白文字を表す。空白、タブ、改行文字、改ページ文字とマッチ
  • 「\d」 :0から9までの数字とマッチ
  • 「\w」 :英数字とマッチ
irb(main):009:0> /ruby\sruby/ =~ "ruby ruby"
=> 0
irb(main):010:0> /ruby\sruby/ =~ "ruby\truby"
=> 0
irb(main):011:0> /ruby\sruby/ =~ "rubyruby"
=> nil
irb(main):012:0> /mysql\d/ =~ "mysql2"
=> 0
irb(main):013:0> /\w\w\w\w\w\w/ =~ "mysql2"
=> 0

####繰り返し

  • 「*」: 0回以上の繰り返し
  • 「+」: 1回以上の繰り返し
  • 「?」: 0回または1回の繰り返し
  • 「{n}」: n回の繰り返し
  • 「{n,m}」: n~m回の繰り返し
  • 「{n,}」: n回以上の繰り返し
irb(main):014:0> /be*r/ =~ "beer"
=> 0
irb(main):015:0> /be+r/ =~ "beer"
=> 0
irb(main):016:0> /be?r/ =~ "beer"
=> nil
irb(main):017:0> /be{2}r/ =~ "beer"
=> 0
irb(main):018:0> /be{3,}r/ =~ "beer"
=> nil

#正規表現のオプション

  • i : アルファベットの大文字と小文字の違いを無視する。
  • x : 正規表現内の空白と、「#」の後ろの文字を無視する。これにより、正規表現中にコメントがかけるようになる。
  • m : 「.」が改行文字にもマッチするようになる。
irb(main):019:0> /ruby/i =~ "Ruby"
=> 0
irb(main):020:0> /ruby xオプションの挙動を調べる/x =~ "ruby"
=> nil
irb(main):021:0> /ruby #xオプションの挙動を調べる/x =~ "ruby"
=> 0
irb(main):022:0> /ruby./ =~ "ruby\n"
=> nil
irb(main):023:0> /ruby./m =~ "ruby\n"
=> 0

#キャプチャ
キャプチャとは、~~後方参照とも呼ばれ、~~正規表現でマッチした部分の一部を取り出すものです。正規表現の中の「()」で囲まれた部分にマッチした文字列を$1,$2といった**$数字**の形の変数で取り出すことができる。

capture.rb
/(.)(.)(.)(.)/ =~ "ruby"
first = $1
second = $2
third = $3
fourth =$4
puts first #=> "r"
puts second #=> "u"
puts third #=> "b"
puts fourth #=> "y"

ただし、「()」は複数のパターンを一つにまとめる時にも使う。過去に書いたプログラの中の正規表現を修正する時に「()」の数を変更すると、本当に参照したい部分のインデックスまで変更されてしまい、何かと不便な場合があります。そのようにキャプチャの必要のないパターンをまとめる場合は、「(?: )」 を使います。

noneedcapture.rb
/(.)(.)+(.)/ =~ "ruby"
puts $1 #=> "r"
puts $2 #=> "b"
puts $3 #=> "y"
/(.)(?:.)+(.)/ =~ "ruby"
puts $1 #=> "r"
puts $2 #=> "y"

また、「$数字」以外にも、マッチした結果を保持する変数として

  • 「$`」: マッチした部分より前の文字列
  • 「$&」: マッチした部分そのものの文字列
  • 「$'」: マッチした部分より後ろの文字列

があります。

othermatch.rb
/u./ =~ "ruby"
puts $` #=> "r"
puts $& #=> "ub"
puts $' #=> "y"

Ruby関連記事

配列で利用できる主なメソッドをまとめてみた[Ruby編]

#最後に
正規表現の基礎的であり重要なものをまとめてみました。また、javascriptとrubyでは同じ記号でも意味の異なるものも多少あるので、時間がある時にそちらもまとめてみたいと思います。正規表現は難しいイメージがありましたが、まとめることでスッキリしました○
使いこなせるように練習を重ねたいと思います。

12
10
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?