This commit is contained in:
Rikuoh Tsujitani 2024-03-23 22:59:51 +09:00
parent 516e3a92d2
commit 39a132c7e8
Signed by: riq0h
GPG key ID: 010F09DEA298C717
3 changed files with 56 additions and 8 deletions

View file

@ -149,6 +149,41 @@ A以外の任意の文字:[^A]で表せる
(?!abc) 否定の先読み (?!abc) 否定の先読み
Web記事読了 Web記事読了
## 3/23
正規表現のマッチ: =~ で比較するとマッチした場合にtrueが返る
Ruby上でキャプチャされた文字列を抜き出すmatchメソッドm = /(\d+)年(\d+)月(\d+)日/.match(text) m[1]などの形式で取得できる
(?<name>)でキャプチャに名前を付けられる m[:name] シンボルで指定する。文字列でもできる
左辺に正規表現リテラルを置いて=~演算子を使うとキャプチャの名前がローカル変数に割り当てられる:ようは#{year}で(?<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が123456になる。ハッシュに渡すこともできる。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<name>のように先頭に\kを加える
なお、公式リファレンスではブロックを使う方法が推奨されている
プログラムの作成を通じて:これはいいものだ
Regexp.new : 正規表現オブジェクトを作成する
%r!文字!: スラッシュをエスケープせずに正規表現を作る
%r{文字}:こっちのほうがわかりやすそう
正規表現オプション: /iは大文字小文字を区別しない /mはドットを改行文字にもマッチさせる /xオプションは改行やスペースが無視されコメントが書ける
Ragexp.last_match : 正規表現のマッチやキャプチャを取得できる。フォーマッタにかけるとこれに置き換わる
match? : マッチするとtrue、しなければfalseを返すのは他と同じだが内容を書き換えないので高速に処理できる
231ページまで

View file

@ -1,4 +1,5 @@
UNITS = { m: 1.0, ft: 3.28, in: 39.37 } def convert_hash_syntax(old_syntax)
def convert_length(length, from: :m, to: :m) old_syntax.gsub(/:(\w+) *=> */) do
(length / UNITS[from] * UNITS[to]).round(2) "#{$1}: "
end
end end

View file

@ -1,10 +1,22 @@
require 'minitest/autorun' require 'minitest/autorun'
require_relative 'main' require_relative 'main'
class ConvertLengthTest < Minitest::Test class ConvertHashSyntaxTest < Minitest::Test
def test_convert_length def test_convert_hash_syntax
assert_equal 39.37, convert_length(1, from: :m, to: :in) old_syntax = <<~TEXT
assert_equal 0.38, convert_length(15, from: :in, to: :m) {
assert_equal 10670.73, convert_length(35_000, from: :ft, to: :m) :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
end end