stringr::str_replace()には置換文字列だけではなく関数も指定できる
stringrパッケージのstr_replace()
/str_replace_all()
は、バージョン1.2.0からreplacement
引数に関数を取ることができます。
これを使うと、「指定した正規表現にマッチした部分だけ大文字にする」みたいなことが簡単にできます。
たとえば、1年前くらいにこれをやろうとすると、以下のように
- 正規表現にマッチするインデックスを取得
- そのインデックスで文字列を抜き出して
toupper()
で大文字に変換 - 元のインデックスの場所を置換
というステップを踏む必要がありました。
library(stringr) hoxo <- "This is hoxo_m" pattern <- "(hoxo)_(m|w|b|x)" m <- str_locate(hoxo, pattern) m #> start end #> [1,] 9 14 # 抜き出す範囲の確認 str_sub(hoxo, start = m[1], end = m[2]) #> [1] "hoxo_m" # 抜き出した部分を置換 str_sub(hoxo, start = m[1], end = m[2]) <- toupper(str_sub(hoxo, start = m[1], end = m[2])) hoxo #> [1] "This is HOXO_M"
(出典:メモ:stringrのstr_locate_allとstr_subを組み合わせて文字列置換 - Technically, technophobic. *1)
これがいまや、以下のように一瞬で書けます。
hoxo <- "This is hoxo_m" pattern <- "(hoxo)_(m|w|b|x)" str_replace(hoxo, pattern, toupper) #> [1] "This is HOXO_M"
もうちょっと複雑な例としては、?str_replace
に面白い例が載っているのでそれをそのまま以下にコピペします。
文字列中に出てくる色の名前をRGB値に置き換えるというものです。
色の名前は1つの文字列中に複数回出てくるので、今回はstr_replace()
ではなくstr_replace_all()
になっています。
colours <- str_c("\\b", colors(), "\\b", collapse="|") col2hex <- function(col) { rgb <- col2rgb(col) rgb(rgb["red", ], rgb["green", ], rgb["blue", ], max = 255) } x <- c( "Roses are red, violets are blue", "My favourite colour is green" ) str_replace_all(x, colours, col2hex) #> [1] "Roses are #FF0000, violets are #0000FF" #> [2] "My favourite colour is #00FF00"
便利!
余談
ついでにちょっと貢献アピールをしておくと、前バージョンではメモ:stringrのstr_locate_allとstr_subを組み合わせて文字列置換 - Technically, technophobic.の最後の例にあるように、正規表現がマッチしないとNA
になってしまうという問題があったのを、stringiとstringrにPRを送って直しました。
興味ある方は以下のissueをご参照ください:
*1:注:この記事を書いたときにすでにstringr 1.2.0はリリースされてたけどこの機能の存在に気付いてなかった...