Rubyベストプラクティス -プロフェッショナルによるコードとテクニック
- 作者: Gregory Brown,高橋征義,笹井崇司
- 出版社/メーカー: オライリージャパン
- 発売日: 2010/03/26
- メディア: 大型本
- 購入: 9人 クリック: 307回
- この商品を含むブログ (47件) を見る
- 作者: 高橋征義,後藤裕蔵,まつもとゆきひろ
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2013/06/04
- メディア: 単行本
- この商品を含むブログ (33件) を見る
instance method String#[]
self[regexp, nth = 0] -> String
slice(regexp, nth = 0) -> String
正規表現 regexp の nth 番目の括弧にマッチする最初の部分文字列を返します。 nth を省略したときや 0 の場合は正規表現がマッチした部分文字列全体を返します。 正規表現が self にマッチしなかった場合や nth に対応する括弧がないときは nil を返します。
このメソッドを実行すると、 マッチ結果に関する情報が組み込み変数 $~ に設定されます。
- [PARAM] regexp:
取得したい文字列のパターンを示す正規表現
- [PARAM] nth:
p "foobar"[/bar/] # => "bar" p $~.begin(0) # => 3 *1 p "def getcnt(line)"[ /def\s+(\w+)/, 1 ] # => "getcnt"
なるほど。
マッチした部分を取るのはString#[/正規表現/]でいけるのね。
String#scanだとこうなる。
instance method String#scan
scan(re) -> [String] | String
self に対して正規表現 re を繰り返しマッチし、 マッチした部分文字列の配列を返します。
正規表現が括弧を含む場合は、 括弧で括られたパターンにマッチした部分文字列の配列の配列を返します。
例:p "foobar".scan(/../) # => ["fo", "ob", "ar"] p "foobarbazfoobarbaz".scan(/ba./) # => ["bar", "baz", "bar", "baz"] p "foobar".scan(/(.)/) # => [["f"], ["o"], ["o"], ["b"], ["a"], ["r"]] p "foobarbazfoobarbaz".scan(/(ba)(.)/) # => [["ba", "r"], ["ba", "z"], ["ba", "r"], ["ba", "z"]]
使い分けできそうですね。String#scanだと必ず配列に入るので、文字列へ戻すのに[0][0]とか付けたりするのが面倒だったんですよ。
何番目じゃなく名前を付けて指定
?<名前>と表記することで正規表現を指定できる。
self[regexp, name] -> String
slice(regexp, name) -> String
正規表現 regexp の name で指定した名前付きキャプチャにマッチする最初の 部分文字列を返します。正規表現が self にマッチしなかった場合は nil を返 します。[PARAM] regexp:
正規表現を指定します。
[PARAM] name:
取得したい部分文字列のパターンを示す正規表現レジスタを示す名前
[EXCEPTION] IndexError:
name に対応する括弧がない場合に発生します。
例:s = "FooBar" s[/(?[A-Z]..)(? [A-Z]..)/] # => "FooBar" s[/(? [A-Z]..)(? [A-Z]..)/, "foo"] # => "Foo" s[/(? [A-Z]..)(? [A-Z]..)/, "bar"] # => "Bar" s[/(? [A-Z]..)(? [A-Z]..)/, "baz"] # => IndexError
便利だけど…逆に読みづらいかも。
*1:$~.begin(0)は0番目のマッチの開始位置。$~.end(0)だと0番目のマッチの終了位置