Rで文字列を扱う人には必須!正規表現を使えるようになろう!

R

Rの文字列操作関数には、正規表現を使って文字列のマッチングを行うものがあります。この関数を使いこなせれば、データ分析の前処理がかなり楽になるはず。ここに載せている正規表現のパターンだけでも、かなり多くの文字列操作ができるはずです。正規表現を覚えてもっと楽に文字列操作できるようになりましょう

str_view(), str_view_all() 関数

正規表現を使える関数として、このページではstr_view(), str_veiw_all()関数のみ使います。str_view()関数は条件にマッチした最初の文字列要素を表示し、str_view_all()関数は条件にマッチしたすべての部分を表示します。RStudioで使用すると、Viewerペインに結果が示されます。正規表現のマッチ結果がとてもわかりやすいので、ぜひ使ってみてください。

str_view(string, pattern, match = NA)
str_view_all(string, pattern, match = NA)
引数 意味
string 評価対象の文字列ベクトル
pattern 探索パターン(正規表現)
match TRUEを指定すると、マッチした要素のみ表示する。
FALSEを指定すると、マッチしなかった要素のみ表示する。
それ以外は両方表示する(デフォルトはNA)下記の例だとTRUEの場合、bananaのみが表示される。
FALSEの場合、appleとpearが表示される。
それ以外の場合、apple, banana, pearのすべてが表示される。
library(stringr)
x <- c("apple", "banana", "pear")
#------------------------
# str_viewの使い方
#------------------------
str_view(x, "an")
str_view_all(x, "an")

str_view()の結果マッチする最初の部分のみがハイライトされている。
str_viewの結果

str_view_all()の結果:マッチするすべての部分がハイライトされている。
str_view_allの結果

任意の1文字とのマッチ

任意の1文字とマッチする正規表現として、以下のようなものがあります。

正規表現 意味
.(ドット、ピリオド) 改行以外の1文字とマッチ
\d 任意の数字1文字とマッチ
\s 任意の空白文字(空白、タブ、改行)とマッチ
\w 任意の単語を構成する文字にマッチ([a-zA-Z0-9])

以下のように覚えると覚えやすいと思います。

d : digitの頭文字
s : spaceの頭文字
w : wordの頭文字

d,s,wを大文字にすると、それ以外の文字にマッチします。

正規表現 意味
\D 任意の数字以外の1文字とマッチ
\S 任意の空白文字以外の1文字とマッチ
\W 任意の単語を構成する文字以外の1文字
x <- c("apple", "2 apples", "apple juice", "-#=")

#  apple, 2 apples, apple juice のaにマッチ
str_view_all(x, "a")

# 2 apples の2にマッチ
str_view_all(x, "\\d")

# 2 apples, apple juiceの空白にマッチ
str_view_all(x, "\\s")

# 2 apples, apple juiceの空白,-#= 以外の文字にマッチ
str_view_all(x, "\\w")

# 2 apples の2以外にマッチ
str_view_all(x, "\\D")

# 2 apples, apple juiceの空白以外にマッチ
str_view_all(x, "\\S")

# 2 apples, apple juiceの空白と-#=にマッチ
str_view_all(x, "\\W")

エスケープ文字

正規表現では「.」が改行以外の任意の文字にマッチするので、文字としての「.」にマッチさせるために、以下のように書いても、すべてのxがマッチしてしまいます。

str_view(x, ".")

これを解消するために、エスケープ文字を使用します。エスケープ文字とは、エスケープ文字を使うことで、その後の文字が別の解釈になるような文字のことです。

文字「.」とマッチするための、”正規表現”の文字列は、「\.」となります。「\」(バックスラッシュ)がエスケープ文字です。

ここで「”正規表現”の文字列」とあえて書きました。

Rでもバックスラッシュがエスケープ文字として用いられるため、Rでバックスラッシュ「\」を表現するためには、「\\」のようにバックスラッシュを2つ重ねる必要があります。したがって、Rで文字「.」とマッチする正規表現は、Rの文字列では「\\.」のように表されます。

正規表現でエスケープ文字を使う場合は、実際の文字(.)、正規表現の文字列(\.)、Rの文字列列(\\.)の3つの意味を意識する必要があります。ややこしいですね。

なお、文字の「\」とマッチするには、正規表現の文字としては「\\」のようにバックスラッシュを2つ重ねる必要がありますので、これをRの文字列として表現するには、「\\\\」のようにバックスラッシュを4つ重ねる必要があります。

x <- c("abc", "a.c", "def")

# "abc", "a.c"にマッチ
str_view_all(x, "a.c")
# "a.c"にマッチ 
str_view_all(x, "a\\.c")

先頭、末尾の指定

「^」、「$」を使用することで、マッチを取りたい文字の位置を指定することができます。

正規表現 意味
^ 文字列の先頭とマッチ
$ 文字列の末尾とマッチ
x <- c("apple", "banana", "pear")

#  "apple"の1文字目にマッチ
str_view_all(x, "^a")

# "banana"の最後の文字にマッチ
str_view_all(x, "a$")

マッチする候補の指定

「○○のうちのどれかにマッチする」のようなパターンを指定することができます。

正規表現 意味
[xyz] x, y, zのどれか1文字とマッチ
[^xyz] x, y, z以外のどれか1文字とマッチ
[a-z] aからzまでの範囲のどれか1文字とマッチ
[0-9] 0から9までの範囲のどれか1文字とマッチ
x|y xまたはyとマッチ
x <- "abcABC123"

# aがマッチする
str_view_all(x, "[ax]")

# a以外がマッチする
str_view_all(x, "[^ax]")

# A,B,Cがマッチする 
str_view_all(x, "[A-Z]")

# 2,3がマッチする
str_view_all(x, "[2-3]")
# Aと2がマッチする
str_view_all(x, "A|2")

「|」の演算は優先順位が低いので注意が必要です。必要に応じてカッコで括る必要があります。

x <- c("xyz", "123", "xyz23", "xy123")

# xyz, 123, xyz23のxyz, xy123の123にマッチする
str_view_all(x, "xyz|123")

# xyz23, xy123にマッチする
str_view_all(x, "xy(z|1)23")

繰り返し

「あるパターンが〇〇回繰り返す」というようなパターンを指定することができます。

正規表現 意味
? ?を後ろにつけると、直前のブロックが0回か1回
+ +を後ろにつけると、直前のブロックが1回以上
* *を後ろにつけると、直前のブロックが0回以上
{n}  (nは数字) {n}を後ろにつけると、直前のブロックがn回
{n,} {n,}を後ろにつけると、直前のブロックがn回以上
{,m}(mは数字) {,m}を後ろにつけると、直前のブロックがm回以下
{n,m}(n, mは数字) {n,m} を後ろにつけると、直前のブロックがn回からm回
x <- "aaabbbccc"

str_view_all(x, "b{2}")   # bが2回繰り返す部分にマッチ(初めのbb)
str_view_all(x, "b{2,}")  # bが2回以上繰り返す部分にマッチ(bbb)
str_view_all(x, "b{1,2}") # bが1回以上2回以下繰り返す部分にマッチ(bb,b)

{n,m}はデフォルトで最長文字列とマッチします。
{n.m}?のように後ろに「?」をつけることで、最短文字列とマッチさせることもできるます。

x <- "aaabbbccc"

# デフォルトでマッチは最長文字列とマッチする
str_view_all(x, "a[bc]+")  # 3番目のa以降(abbbccc)がマッチ

str_view_all(x, "a[bc]+?") # 3番目のaとその次のbのみがマッチ(ab)

グループ化とキャプチャ(後方参照)

正規表現「a+b」で、aが1回以上続いたのち、bが続く文字列をマッチすることができます。ここではaという1文字が繰り返すパターンを考えましたが、括弧を使用することで、複数文字にも対応できるようになります。正規表現「(ab)+c」とすれば、abという2文字が1回以上繰り返して、その後にcという文字が続くパターンをマッチできます。

x <- c("Aaabbb", "AbcababcbA")

# Aaabbbのaab, AbcababcbAの2回のabがマッチする
str_view_all(x, "a+b")

# AbcababcbAのababcがマッチする
str_view_all(x, "(ab)+c")

()でグループ化すると、キャプチャも同時に行われます。キャプチャというのは、()内の文字列を記憶し、後で参照できるようにする機能のことです。記憶した文字列は、後で正規表現で「\1」, 「\2」, 「\3」, …のように指定することで利用することができます(これを後方参照と言います)。

x <- c("banana", "coconut", "pinapple", "grape", "papaya")

# bananaのanan, coconutのcoco, papayaのpapaがマッチする
str_view_all(x, "(..)\\1")

なお、(?:)を使用することで、グループ化のみ行い、キャプチャを行わないようにすることもできます。

まとめ

今回、以下のパターンの正規表現について紹介しました。

  • 文字のマッチ
  • 先頭、末尾の指定
  • マッチする候補の指定
  • 繰り返し
  • グループ化
  • キャプチャ(後方参照)

ここで紹介したもの以外にも正規表現のパターンはありますが、このパターンだけでも、かなり多くの文字列操作ができるはずです。ぜひ、stringrと組み合わせて使ってみてください。

R : stringrで文字列を検索、置換
Rで文字列操作を行う場合、baseRでもstringrでもどちらでも行える内容はほぼ同じです。このページでは、stringrに対応するbaseRの文字列操作関数を示しつつ、stringrの使い方をまとめています。