読者です 読者をやめる 読者になる 読者になる

脳汁portal

アメリカ在住(だった)新米エンジニアがその日学んだIT知識を書き綴るブログ

正規表現Tips18選

正規表現のTipsでよく使う記法等をTipsとして残します。

宣言方法

//
%r{}
  • %r{}の括弧内に書くことで正規表現を表せます
Regexp.new()

正規表現文法

文頭指定(^)
  • ^をつけると文頭を表す意味になります
  • 文中に指定した文字があってもマッチしません。
def test(str, reg)
  if str =~ reg
    puts 'match!!'
  else
    puts 'unmatch...'
  end
end

puts test('foobar', Regexp.new(/^foo/)) # ==> match!!
puts test('foobar', Regexp.new(/^bar/)) # ==> unmatch...
文末指定($)
  • ^をつけると文末を表す意味になります
  • 文中に指定した文字があってもマッチしません。
puts test('foobar', Regexp.new(/foo$/)) # ==> unmatch...
puts test('foobar', Regexp.new(/bar$/)) # ==> match!!
任意文字指定([])
  • []内に入れた文字のどれかに一致するという意味になります
  • [a-z]や、[0-9]で一括指定することが出来ます
puts test('foo', Regexp.new(/fo[a-z]/))  # ==> match!!
puts test('foo', Regexp.new(/fo[0-9]/))  # ==> unmatch...
任意文字指定の否定([^])
  • 指定範囲内の文頭に^をつけることで、その後に指定した範囲以外ということを表せます
puts test('foo', Regexp.new(/fo[^a-z]/))  # ==> unmatch...
puts test('foo', Regexp.new(/fo[^0-9]/))  # ==> match!!

繰り返し

0回以上(*)
  • []や()の後に*をつけることにより、括弧内の指定が0回以上繰り返されることを表します
  • 0回も含まれるので、出現しないことも含みます
puts test('foo', Regexp.new(/fo[o]*/))   # ==> match!!
puts test('foo', Regexp.new(/foo[o]*/))  # ==> match!!
1回以上(+)
  • []や()の後に+をつけることにより、括弧内の指定が1回以上繰り返されることを表します
  • 1回以上なので、出現しない場合はマッチしません
puts test('foo', Regexp.new("f[o]+"))    # ==> match!!
puts test('foo', Regexp.new("foo[a]+"))  # ==> unmatch...
回数指定
  • {}内に範囲を指定することで、繰り返しの回数を指定することが出来ます
  • {x,}でx回以上
  • {,y}でy回以下
  • {x,y}でx回以上y回以下
puts test('foo', Regexp.new(/fo[o]{0,}/))  # ==> match!!  
puts test('foo', Regexp.new(/f[o]{,2}/))   # ==> match!!  
puts test('foo', Regexp.new(/f[o]{2,3}/))  # ==> match!!  
puts test('foo', Regexp.new(/f[o]{5,6}/))  # ==> unmatch...

ワイルドカード

空白(\s)
  • \sで空白文字(space)を表します
puts test('foo bar', Regexp.new(/foo\sbar/))  # ==> match!!
数字(\d)
  • \sで数字(digit)を表します
puts test('foo1bar', Regexp.new(/foo\\dbar/))  # ==> match!!
ワイルドカード(メタキャラクタ)打ち消し(\\)
  • 正規表現の中で、文字列として'\'を使いたい場合は\\と連続することで特殊文字としての機能を打ち消せます
puts test('foo\bar', Regexp.new(/foo\\bar/))  # ==> match!!
puts test('foo\bar', Regexp.new(/foo\bar/))   # ==> unmatch...

条件

else条件(|)
  • |でつなぐことで、複数の条件を指定できます
puts test('foo', Regexp.new(/foo|bar|baz/))  # ==> match!!

マッチしたワードの取得

$n
  • 正規表現内の条件を括弧でくくることで、前方から順番に$1, $2, ....として呼び出せます。
  • Javascriptの場合はRegExp.$n
if 'foobar' =~ /f([o]+)b(ar)/
  puts $1  # ==> oo
  puts $2  # ==> ar
end
入れ子にした場合
  • 外側から順番に$nに格納されます
if 'foobar' =~ /f(o(ob)a)r/
  puts $1  # ooba
  puts $2  # ob
end

最長一致の原則

if 'foobarhoo' =~ /(fo[a-z]*)/
  puts $1  # ==> foobarhoo
end
  • 上の正規表現はfooにもfoobarにもあてはまりますが、この場合は最長のマッチしたパターンが採用されます

elseは条件毎に最後まで判定する

if 'hoges fuga' =~ /^(hoge|hoges)\s*(.*)$/
  puts $1 # hoge
  puts $2 # s fuga
end
  • 以下のような条件文の場合、(hoge)\s(.*)を判定した後に、(hoges)\s(.*)を判定します。
  • hogesを先に判定させたい場合は、先に書くか
if 'hoges fuga' =~ /^(hoges|hoge)\s*(.*)$/
  puts $1 # hoges
  puts $2 # fuga
end
  • 後ろの条件を更に明確にします
if 'hoges fuga' =~ /^(hoge|hoges)(\s(.*))*$/
  puts $1 # hoges
  puts $2 #  fuga
end