1
0

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.

キャプチャ数が動的に変化する正規表現の具体例

Posted at

この前たのしいRubyを買いまして、絶賛勉強中です。
問題演習中にはまったところがあったのでまとめておこうと思います。

アルファベットとハイフンから構成される文字列を、ハイフンで区切って単語部分についてcapitalizeする

splitすることで簡単にできます。

rubypractice_342.rb
def word_capitalize_split(str) # str = "ruby-php-Python-COBOL-JavaScript-javA"
  nstr = []
  result_split = ""
  nstr = str.split(/-/) # ハイフンで分割し配列に格納
  nstr.each do |word|
    result_split << word.capitalize + "-" # 単語をCapitalizeしハイフンと一緒に文字列に入れる
  end
  return result_split.chop # "Ruby-Php-Python-Cobol-Javascript-Java"
end

しかし、この問題は正規表現クラスの章末問題でした。なので正規表現でも解いてみましょう。(実はもっと簡単にできたりしないかな・・・)

rubypractice_342.rb
def word_capitalize_regexp(str) # str = "ruby-php-Python-COBOL-JavaScript-javA"
  count = 0
  str.each_char do |n| # 単語の中のハイフンの数を数える
    if n == "-"
      count += 1
    end
  end

  if count > 0
    separator = "(.+)"
    for i in 1..count
      separator << "-(.+)" #ハイフンの数だけセパレーターに追加する
    end

    Regexp.new(separator) =~ str # ハイフン区切りで単語をキャプチャ
    result = $1.capitalize # 一つ目のキャプチャした単語をCapitalize
		# ex.1 ハマったところここから
    for i in 2..count + 1
      result << "-" + eval('$'+i.to_s).capitalize # 二つ目以降のキャプチャした単語をCapitalize
    end
		# ex.1 ここまで
    return result # "Ruby-Php-Python-Cobol-Javascript-Java"
  else
    return str.capitalize
  end
end

ここで、メソッドに渡される文字列strにはハイフンがいくつ入ってくるかわからないので、キャプチャする単語数も動的に変化する点が問題となりました。
例えば、strにくる単語は"ruby-JavaScript-javA"かもしれないし、"ruby-php-Python-COBOL-JavaScript-javA"かもしれないという感じです。separatorは"(.+)-(.+)-(.+)"や"(.+)-(.+)-(.+)-(.+)-(.+)-(.+)"でええやろ、となったのですが・・・

evalによるコード評価

最初はex1部分は下のように書いてありました。

rubypractice_342.rb
    for i in 2..count + 1  
      result << "-" + "$#{i}".capitalize  
    end  
 

しかし、この場合の結果は"ruby-php-Python" => "Ruby-$2-$3"となってしまいます。
どうやら、$2や$3が文字列オブジェクトではなくリテラルとして処理されてしまっているようです。
そこで、このリテラルがRubyのコードとして評価してもらえるよう、evalメソッドを使用します。

rubypractice_342.rb
    for i in 2..count + 1
      result << "-" + eval('$'+i.to_s).capitalize # 二つ目以降のキャプチャした単語をCapitalize
    end
 

これにより、文字列部分がプログラムとして実行され、想定どおりに結果が得られます。

参考

Rubyでメタプログラミングことはじめ

1
0
3

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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?