まずは蝋の翼から。

学んだことを書きながら確認・整理するためのメモブログ。こういうことなのかな?といったことをふわっと書いたりしていますが、理解が浅いゆえに的はずれなことも多々あると思うのでツッコミ歓迎

正規表現で文字列からほしい部分を抽出する

Rでstr_match_all(string, pattern)でstringに対してマッチしたpattern文字列を抽出する。

pattern部分は()を入れることでpattern中の一部分だけを取ることができる。

listの1要素目がマッチした部分の全体、2要素目以降が括弧でマッチさせた抽出される。

_allがないstr_matchの場合ははじめに一致したもののみlistで取得。
_allありはstr_matchの場合は一致したものがすべてMatrixで取得。

www.rdocumentation.org

実例

model_hoge:fuga_piyo:fugaという文字列から、_:に挟まれた部分hogepiyoを取り出したい。
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"

参考

heavywatal.github.io

murashun.jp