正規表現で文字列からほしい部分を抽出する
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"