Ruby入門5、正規表現まとめ~これからにRubyに乗り換えする人へ~

| コメント(0) | トラックバック(1)

今回は正規表現をまとめてみました。

# 正規表現
  /patern/        スラッシュで囲む
  p = %r!patern!  %表記

# 演算子
  =~  一致する
  !~  一致しない

# メタ文字

  [abc]     a b cとマッチ
  [a-z]     abcdefg..zとマッチ
  [a-zA-Z]  abcdefg..z ABC..Zとマッチ
  [^a]      a以外の文字

  \A        文字列の先頭
  \Z        文字列の末尾 \nでマッチ
  \z        文字列の末尾 \nではマッチされない
  ^         文字列の行頭 単語の先頭 !!文字列の途中でもマッチする!!
  $         文字列の末尾 単語の末尾 !!文字列の途中でもマッチする!!
  .         1文字
  \s        スペース
  \S        スペース以外
  \d        数字
  \D        \d以外
  \w        英数字と_ [0-9a-zA-Z_] 日本語1文字
  \W        \w以外
  \b        単語の境界
  \B        単語の一部

  (...)     正規表現のグルーピング Capture
  (a|b)     a or b
  a*        直前の正規表現と0回以上マッチ
  a?        0回(なし)か1回マッチ
  a+        1回以上マッチ
  a{3}      3回繰り返し時にマッチ
  a{3,}     3回以上繰り返しにマッチ
  a{3,6}    3回以上 6回以下マッチ
  a*?       0回以上マッチ(最短一致)
  a+?       1回以上マッチ(最短一致)

  (:?)      後方参照不要な場合
  (?>)      強欲マッチ
  (?=re)    先読み

# オプション
  //i       大小文字関係なし
  //m       複数行
  //o       式展開時の高速化
  //x       スペースやコメント追加

# 後方参照取得
  $~        Regexp.last_match                MatchData
  $&        Regexp.last_match(0)             Matchした文字列
  $1 $2     Regexp.last_match(1)             /(.*)(.*)/のn番目
  $+        Regexp.last_match(-1)            /(.*)(.*)/の最後
  $`     #` Regexp.last_match(1).pre_match   Matchした文字列より前方
  $'     #' Regexp.last_match(1).post_match  Matchした文字列より後方
ruby
# -*- coding: utf-8 -*-
# 正規表現
# 
str = "abcdef"
str =~ /^a/            # => 0
str =~ /^b/            # => nil
str =~ /c/             # => 0
# 日本語
str = "正規表現"
str =~ /^正/                    # => 0

# 文字列から正規表現
#
pat = "[0-9a-zA-Z]*"
"1234".match(/#{pat}/)          #=> #<MatchData "1234">

# 文字列にマッチする正規表現を作成
#
url = "http://mukaer.com/"
Regexp.escape(url)                 # => "http://mukaer\\.com/"
url.match(/#{Regexp.escape(url)}/) # => #<MatchData "http://mukaer.com/">
# Regexp.unionで一回
Regexp.union(url)               # => /http:\/\/mukaer\.com\//
url.match(Regexp.union(url))    # => #<MatchData "http://mukaer.com/">

# 大小文字どちらでもマッチ
#   i
# 
str = "This is a Pen"
str =~ /^this/i                 # => 0
str =~ /^this/                  # => nil

# 複数行マッチ
#   m
# 
str = "one\ntwo\nthree"
str.match(/one.two.three/)      # => nil
str.match(/one.two.three/m)     # => #<MatchData "one\ntwo\nthree">

# 式展開の正規表現を高速化
#   ただし同じ式のばあいのみ有効
#  o
#
reg = "[0-9]+"
["0","1","2","3","a","b","c"].select { |s| s.match(/#{reg}/)  } #遅い
["0","1","2","3","a","b","c"].select { |s| s.match(/#{reg}/o) } #早い
#間違った例
str = "insert"
["select","insert","update","delete","create","drop"].select { |s| s.(/#{s}/o) }
  # => nil

# 正規表現のmatch情報取得
# 
str = "<<-=-=-ヤシマ作戦決行は1800時から、目標は25%削減YO-=-=->>"
result = str.match(/ヤシマ作戦決行は([0-9]{4})時から、目標は([\d]*)%削減YO/)
$~                   # => #<MatchData "ヤシマ作戦決行は1800時から、目標は25%削減YO" 1:"1800" 2:"25">
$&                   # => "ヤシマ作戦決行は1800時から、目標は25%削減YO"
$1                   # => "1800"
$2                   # => "25"
$+                   # => "25"
result               # => #<MatchData "ヤシマ作戦決行は1800時から、目標は25%削減YO" 1:"1800" 2:"25">
result[0]            # => "ヤシマ作戦決行は1800時から、目標は25%削減YO"
result[1]            # => "1800"
result[2]            # => "25"
result[-1]           # => "25"
Regexp.last_match    # => #<MatchData "ヤシマ作戦決行は1800時から、目標は25%削減YO" 1:"1800" 2:"25">
Regexp.last_match(0) # => "ヤシマ作戦決行は1800時から、目標は25%削減YO"
Regexp.last_match(1) # => "1800"
Regexp.last_match(2) # => "25"
Regexp.last_match(-1)           # => "25"
# 正規表現にマッチより前方取得
$`                 #`           # => "<<-=-=-"                                            #`
result.pre_match                # => "<<-=-=-"
# 正規表現にマッチより後方取得
$'                 #'           # => "-=-=->>"                                            #'
result.post_match               # => "-=-=->>"
# オフセット取得(始点と終点)
str.length                      # => "25"
str[0]                          # => "ヤ"
str[26]                         # => nil
result.offset(0)                # => [0, 26]
result.offset(1)                # => [8, 12]
result.offset(2)                # => [19, 21]
# オフセット 始点
result.begin(0)                 # => 0
result.begin(1)                 # => 8
result.begin(2)                 # => 19
# オフセット 終点
result.end(0)                   # => 26
result.end(1)                   # => 12
result.end(2)                   # => 21

# マッチから抜き出す
#
str = "[[preload preimage preholiday preinstall president]]"
# preから始まる文字を抜き出す
str.scan(/\bpre\w*/)            # => ["preload", "preimage", "preholiday", "preinstall", "president"]
# 1つ抜き出す
str[ /\bpre\w*/ ]               # => "preload"
$~                              # => #<MatchData "preload">
$&                              # => "preload"

# 複数抜き出す
# 
h = <<EOH
HTTP/1.1 200 OK
Date: Wed, 04 May 2011 00:00:00 GMT
Content-Type: text/html
Content-Language: ja

Hello World!!
EOH
# マッチの取得
h.scan(/^\S+:/)                 # => ["Date:", "Content-Type:", "Content-Language:"]
# ()付きの例  多重配列になる
h.scan(/^(.+?): (.+)$/)
   # => [["Date", "Wed, 04 May 2011 00:00:00 GMT"], ["Content-Type", "text/html"], ["Content-Language", "ja"]]
# (())付きの例  は全体も返す
h.scan(/^((.+?): (.+))$/)
   #=> [["Date: Wed, 04 May 2011 00:00:00 GMT", "Date", "Wed, 04 May 2011 00:00:00 GMT"],
   #    ["Content-Type: text/html", "Content-Type", "text/html"],
   #    ["Content-Language: ja", "Content-Language", "ja"]]

# ()がひとつの場合の取り出し方 .flatten
h.scan(/(^\S+):/)               # => [["Date"], ["Content-Type"], ["Content-Language"]]
h.scan(/(^\S+):/).flatten       # => ["Date", "Content-Type", "Content-Language"]

# 文字列の置き換え
#
html = "<ul><li>hoge</li><li>fuga</li></ul>"
# 最初の一致を置換
html.sub( /[>]/ ,">\n")
    #=> "<ul>\n<li>hoge</li><li>fuga</li></ul>"
# すべて置換
html.gsub( /[>]/ ,">\n")
    # => "<ul>\n<li>\nhoge</li>\n<li>\nfuga</li>\n</ul>\n"
# 後方参照と合わせ技
html.gsub( %r!.*<li>(.+)</li><li>(.+)</li>.*! ,'\1  \2')
    # => "hoge  fuga"


・絶賛おすすめ参考書



・正規表現のおすすめ参考書

関連記事

トラックバック(1)

トラックバックURL: http://mukaer.com/cgi-bin/mt/mt-tb.cgi/42

PukiWiki Plus! (PukiWiki/TrackBack 0.4) - FrontPage/Build/Application/Fluentd1.1 (2014年12月15日 16:37)

概要 構成 td_agent_Install(集約サーバー) fluent_agent_lite_Install(ログ送信側) Se... 続きを読む

コメントする

PR

PR





検索

Loading

メニュー

twitter