diff --git a/cherry.txt b/cherry.txt index c607afb..4bc978c 100644 --- a/cherry.txt +++ b/cherry.txt @@ -149,6 +149,41 @@ A以外の任意の文字:[^A]で表せる (?!abc) : 否定の先読み Web記事読了 +## 3/23 +正規表現のマッチ: =~ で比較するとマッチした場合にtrueが返る +Ruby上でキャプチャされた文字列を抜き出すmatchメソッド:m = /(\d+)年(\d+)月(\d+)日/.match(text) m[1]などの形式で取得できる +(?)でキャプチャに名前を付けられる m[:name] シンボルで指定する。文字列でもできる +左辺に正規表現リテラルを置いて=~演算子を使うとキャプチャの名前がローカル変数に割り当てられる:ようは#{year}で(?)の中身が返る +↑変数に一旦入れると機能しない +組み込み変数:$~でオブジェクト全体、$&でマッチした部分全体、$1などでキャプチャを取得できる +scanメソッド:引数で渡した正規表現にマッチする部分を配列に入れて返す '123 456 789'.scan(/\d+/)で["123","456","789"]が返る +↑正規表現に()があるとキャプチャされた部分が二次元配列の内側に入って返る。グループ化はしたいがキャプチャはしたくない(全体を取得したい)場合は(?:)で除外を行う +[]に正規表現を渡すと、文字列から正規表現にマッチした部分を抜き出す: text[/\d{3}-\d{4}/]で"123-4567" +↑マッチする部分が複数ある場合は最初にマッチした文字列のみ返る +キャプチャを使うと第2引数で何番目のキャプチャを取得するか指定できる: tex[/(\d+)年(\d+)月(\d+)日/, 3]で"17"が返る +キャプチャに名前を付けていると第2引数も名前で指定できる +sliceメソッドは[]のエイリアスメソッドでつまり同じ効果を持つ:slice!で破壊的に取り除かれる +splitメソッドに正規表現を渡すとマッチした文字列を区切り文字にして分解して配列として返す:text.split(/,|-/) でカンマまたはハイフンを区切り文字にするの意味になる +gsubメソッド:第1引数の正規表現にマッチした文字列を第2引数の文字列で置き換える text.gsub(',', ':')で123,456が123−456になる。ハッシュに渡すこともできる。hash = {',' => ':'} text.gsub(/,|-/, hash)で123,456-789が123:456/789になる +第2引数を渡す代わりにブロックの戻り値で置き換える文字列を指定できる:text.gsub(/,|-/){ |matched| matched == ',' ? ':' : '/' } +gsubとキャプチャを組み合わせて文字列を置換する:text.gsub(/(\d+)年(\d+)月(\d+)日/, '\1-\2-\3') このように連番指定は\1、\2の形で行う +↑ただし文字列をシングルクオートで囲うかダブルクオートで囲うかで書き方がかなり変わる。後者の場合はバックスラッシュが2つ必要なのでかなり面倒。そこでブロックを使うやり方も考慮に入る。: text.gsub(/\(d+)年(\d+)月(\d+)日/) do "#{$1}-#{$2}-#{$3}" end +キャプチャが文字列の場合は\kのように先頭に\kを加える +なお、公式リファレンスではブロックを使う方法が推奨されている +プログラムの作成を通じて:これはいいものだ +Regexp.new : 正規表現オブジェクトを作成する +%r!文字!: スラッシュをエスケープせずに正規表現を作る +%r{文字}:こっちのほうがわかりやすそう +正規表現オプション: /iは大文字小文字を区別しない /mはドットを改行文字にもマッチさせる /xオプションは改行やスペースが無視されコメントが書ける +Ragexp.last_match : 正規表現のマッチやキャプチャを取得できる。フォーマッタにかけるとこれに置き換わる +match? : マッチするとtrue、しなければfalseを返すのは他と同じだが内容を書き換えないので高速に処理できる +231ページまで + + + + + + diff --git a/main.rb b/main.rb index ae096aa..e755315 100644 --- a/main.rb +++ b/main.rb @@ -1,4 +1,5 @@ -UNITS = { m: 1.0, ft: 3.28, in: 39.37 } -def convert_length(length, from: :m, to: :m) - (length / UNITS[from] * UNITS[to]).round(2) +def convert_hash_syntax(old_syntax) + old_syntax.gsub(/:(\w+) *=> */) do + "#{$1}: " + end end diff --git a/main_test.rb b/main_test.rb index a17b51f..197d000 100644 --- a/main_test.rb +++ b/main_test.rb @@ -1,10 +1,22 @@ require 'minitest/autorun' require_relative 'main' -class ConvertLengthTest < Minitest::Test - def test_convert_length - assert_equal 39.37, convert_length(1, from: :m, to: :in) - assert_equal 0.38, convert_length(15, from: :in, to: :m) - assert_equal 10670.73, convert_length(35_000, from: :ft, to: :m) +class ConvertHashSyntaxTest < Minitest::Test + def test_convert_hash_syntax + old_syntax = <<~TEXT + { + :name => 'Alice', + :age => 20, + :gender => :famle + } + TEXT + expected = <<~TEXT + { + name: 'Alice', + age: 20, + gender: :famle + } + TEXT + assert_equal expected, convert_hash_syntax(old_syntax) end end