正規表現で文字列からほしい部分を抽出する
Rでstr_match_all(string, pattern)
でstringに対してマッチしたpattern文字列を抽出する。
pattern部分は()
を入れることでpattern中の一部分だけを取ることができる。
listの1要素目がマッチした部分の全体、2要素目以降が括弧でマッチさせた抽出される。
_all
がないstr_match
の場合ははじめに一致したもののみlistで取得。
_all
ありはstr_match
の場合は一致したものがすべてMatrixで取得。
実例
model_hoge:fuga_piyo:fuga
という文字列から、_
と:
に挟まれた部分hoge
とpiyo
を取り出したい。
patternとしては、_
, _以外の文字列複数文字
, :
というpatternのうち、_以外の文字列複数文字
を抽出したい。そのため、以下になる
library(tidyverse) str_i = 'model_hoge:fuga_piyo:fuga' # str_match_all str_matced_i_all = str_match_all(str_i, '_([^_])+:') # [[1]] # [,1] [,2] # [1,] "_hoge:fuga" "hoge" # [2,] "_piyo:fuga" "piyo" str_matced_i_all[[1]][1,2] # => hoge str_matced_i_all[[1]][2,2] # => piyo # str_match str_i_matced = str_match(str_i, "_([^_])+:fuga") # [,1] [,2] # [1,] "_hoge:fuga" "hoge" str_i_matced[2] # => hoge
正規表現部分解説
patternの'([^]+):'について。
[^]
は[]内にある文字以外を指す。そのため、[^_]
は_
以外の文字列となり、[^_]+
は_以外の文字複数個
となる。
つまり、「'([^]+):'は_
と:
で囲まれた_以外の文字複数個
部分」がマッチするうち、()
内の_以外の文字複数個
が抽出される。
今回わざわざ_以外の文字複数個
としているのは、文字が_..._..._
となっていて_
が繰り返されている部分も一致するのでそうしないと_を含む箇所も抽出されてしまうため。
str_matced = str_match_all(str_i, "_(.+):fuga") # [[1]] # [,1] [,2] # [1,] "_hoge:fuga_piyo:fuga" "hoge:fuga_piyo"