R入門
正規表現
最終更新:
r-intro
目次
- 目次
- 文字列に特定の文字列が含まれているか調べる
- 文字列が指定の正規表現とマッチするか調べる
- 正規表現を使用して文字列の置き換えを行う
- 正規表現による文字列の比較
- 正規表現による文字列の比較
- 正規表現のマッチをテストする
- 正規表現を使用して文字列を別の文字列に置換する
- 正規表現を使用して文字列を別の文字列に置換する
- 正規表現を使用して任意の長さの文字列を検索する
- ファイル名を示す文字列から拡張子を削除する
- 文字列から正規表現にマッチする文字列を抜き出す
- 正規表現を使用してファイル名を表す文字列から拡張子を消す
- 正規表現を使用してファイル名を表す文字列から拡張子を抜き出す
- 正規表現を使用していずれかの文字列にマッチする文字列を抜き出す
- パターンにマッチするか否かを論理値で返す
- パターンにマッチするか否かを論理値で返す
文字列に特定の文字列が含まれているか調べる
grep関数を使う。以下、使用例。
> s <- c("ABC", "abc", "ABc")
> grep("AB", s)
[1] 1 3
> grep("c", s)
[1] 2 3
> grep("c", s, value = TRUE)
[1] "abc" "ABc"
最初の例では文字列「AB」が含まれるのは1番目と3番目の要素のため、1と3が返される。最後の例ではvalueオプションをTRUEにすることで、インデックスではなく含まれる要素の値そのものを返している。
> grep("d", s)
integer(0)
> grep("d", s, value = TRUE)
character(0)
指定した文字列が見つからなければ空のベクトルが返される。
検索に、正規表現も使える。第一引数にパターンを指定する。
> s <- c("あいう", "いうあ", "うあい")
> grep("^あ", s, value = TRUE)
[1] "あいう"
> grep("あ$", s, value = TRUE)
[1] "いうあ"
> grep("[あ]", s, value = TRUE)
[1] "あいう" "いうあ" "うあい"
文字列が指定の正規表現とマッチするか調べる
grep関数を使う。「ABC」、「abc」、「123」からなる文字列型ベクトルから「a」が含まれる要素があるか否か調べる。
> s <- c("ABC", "abc", "123")
> grep("[a]", s)
[1] 2
その要素自体を取り出す。
> grep("[a]", s, value = TRUE)
[1] "abc"
「A」か「a」が含まれている要素のインデックスを取り出す。
> grep("[Aa]", s)
[1] 1 2
「Z」が含まれている要素のインデックスを取りだしてみる。「Z」が含まれている要素はないので、長さが0の数値型ベクトルが返される。
> grep("[Z]", s)
integer(0)
正規表現を使用して文字列の置き換えを行う
gsub関数を使う。ただ文字列を置換するのではなく、パターンに含まれる文字列を使用して置き換えたい場合は、キャプチャによるグループ化を利用する。パターン内で( )(括弧)に挟まれた範囲はグループ化(キャプチャという)される。このグループには、キャプチャされた順番に1から始まる連番が付けられ、置換後の文字列で\1, \2, …と挿入することで、置換後の文字列に挿入することができる(実際にはエスケープシーケンスを使用する必要があるので、\\1, \\2, …とする)。
以下は、gsub関数を使用して7桁の数字(○○○○○○○)を郵便番号の表記(○○○-○○○○)に置き換えた例。
> s <- c("1234567", "9876543", "3210")
> gsub("([0-9]{3})([0-9]{4})", "\\1-\\2", s)
[1] "123-4567" "987-6543" "3210"
正規表現による文字列の比較
grepl関数を使う。grepl関数はマッチしたらTRUE、そうでなければFALSEを返すので、要素の数が一つの文字列型ベクトルを与えれば、文字列の比較に使うことが出来る。
> s <- c("ABC", "ABCD", "BCD", "CD")
> grepl("^AB", s)
[1] TRUE TRUE FALSE FALSE
> grepl("CD$", s)
[1] FALSE TRUE TRUE TRUE
> if (grepl("^AB", "BCD")) {cat("OK\n")}
> if (grepl("^AB", "ABC")) {cat("OK\n")}
OK
正規表現による文字列の比較
stringrパッケージのstr_detect関数を使う。str_detect関数はマッチしたらTRUE、そうでなければFALSEを返すので、要素の数が一つの文字列型ベクトルを与えれば、文字列の比較に使うことが出来る。
> library(stringr)
> s <- c("ABC", "ABCD", "BCD", "CD")
> str_detect(s, "^AB")
[1] TRUE TRUE FALSE FALSE
> str_detect(s, "CD$")
[1] FALSE TRUE TRUE TRUE
> if (str_detect("BCD", "^AB")) {cat("OK\n")}
> if (str_detect("ABC", "^AB")) {cat("OK\n")}
OK
正規表現のマッチをテストする
stringrパッケージのstr_view関数を使う。str_viewは引数に文字列型ベクトルだけを与えると、その中身を表示するだけで、第2引数にパターンを指定すると、そのパターンにマッチする要素だけを表示し、どこがマッチしているのかわかるように表示してくれる。
> library(stringr)
> s <- c("ABC", "ABc", "Abc", "abc")
> str_view(s)
[1] | ABC
[2] | ABc
[3] | Abc
[4] | abc
> str_view(s, "B")
[1] | A<B>C
[2] | A<B>c
> str_view(s, "bc$")
[3] | A<bc>
[4] | a<bc>
> str_view(s, "[A-Z]{4}")
> str_view(s, "[A-Z]{2}")
[1] | <AB>C
[2] | <AB>c
正規表現を使用して文字列を別の文字列に置換する
gsub関数を使う。元となる文字列にはベクトルを指定することができる。
> s <- c("ABCD", "BCDE", "CDEF")
> gsub("B", "b", s)
[1] "AbCD" "bCDE" "CDEF"
> gsub("^B", "b", s)
[1] "ABCD" "bCDE" "CDEF"
> gsub("[E-F]", "b", s)
[1] "ABCD" "BCDb" "CDbb"
> gsub("[E-F]$", "b", s)
[1] "ABCD" "BCDb" "CDEb"
ただ文字列を置換するのではなく、パターンに含まれる文字列を使用して置き換えたい場合は、キャプチャによるグループ化を利用する。パターン内で( )(括弧)に挟まれた範囲はグループ化(キャプチャという)される。このグループには、キャプチャされた順番に1から始まる連番が付けられ、置換後の文字列で\1, \2, …と挿入することで、置換後の文字列に挿入することができる(実際にはエスケープシーケンスを使用する必要があるので、\\1, \\2, …とする)。
以下は7桁の数字(○○○○○○○)を郵便番号の表記(○○○-○○○○)に置き換えた例。
> s <- c("1234567", "9876543", "3210")
> gsub("([0-9]{3})([0-9]{4})", "\\1-\\2", s)
[1] "123-4567" "987-6543" "3210"
正規表現を使用して文字列を別の文字列に置換する
stringrパッケージのstr_replace_all関数を使う。元となる文字列にはベクトルを指定することができる。str_replaceという別の関数もあり、こちらは各文字列で最初にパターンにマッチした箇所しか置換をしない。
> library("stringr")
> s <- c("ABCD", "BCDE", "CDEF")
> str_replace_all(s, "B", "b")
[1] "AbCD" "bCDE" "CDEF"
> str_replace_all(s, "^B", "b")
[1] "ABCD" "bCDE" "CDEF"
> str_replace_all(s, "[E-F]$", "b")
[1] "ABCD" "BCDb" "CDEb"
> str_replace_all(s, "[E-F]", "b")
[1] "ABCD" "BCDb" "CDbb"
> str_replace(s, "[E-F]", "b")
[1] "ABCD" "BCDb" "CDbF"
ただ文字列を置換するのではなく、パターンに含まれる文字列を使用して置き換えたい場合は、キャプチャによるグループ化を利用する。パターン内で( )(括弧)に挟まれた範囲はグループ化(キャプチャという)される。このグループには、キャプチャされた順番に1から始まる連番が付けられ、置換後の文字列で\1, \2, …と挿入することで、置換後の文字列に挿入することができる(実際にはエスケープシーケンスを使用する必要があるので、\\1, \\2, …とする)。
以下は7桁の数字(○○○○○○○)を郵便番号の表記(○○○-○○○○)に置き換えた例。
> s <- c("1234567", "9876543", "3210")
> str_replace_all(s, "([0-9]{3})([0-9]{4})", "\\1-\\2")
[1] "123-4567" "987-6543" "3210"
正規表現を使用して任意の長さの文字列を検索する
「.」と「{n}」を使う。パターンでは「.」は\n以外の任意の一文字を示す。「{n}」は直前の文字をn回繰り返す意味になる。なお、「{n,}」とするとn回以上という意味になる。
> s <- c("a", "ab", "abc", "abcd")
> grep("^.$", s)
[1] 1
> grep("^.$", s, value = TRUE)
[1] "a"
> grep("^..$", s, value = TRUE)
[1] "ab"
> grep("^.{2}$", s, value = TRUE)
[1] "ab"
> grep("^.{2,}$", s, value = TRUE)
[1] "ab" "abc" "abcd"
> s <- c("この葉", "木の葉", "樹木の葉")
> grep("の", s, value = TRUE)
[1] "この葉" "木の葉" "樹木の葉"
> grep("^.の", s, value = TRUE)
[1] "この葉" "木の葉"
ファイル名を示す文字列から拡張子を削除する
ファイル名を文字列型ベクトルに格納して、gsub関数で正規表現を使えば簡単に削除できる。以下、例。
> s <- c("abc", "abc.def", "abc.def.ghi")
> gsub("\\.[^\\.]+$", "", s)
[1] "abc" "abc" "abc.def"
「¥¥.」は「.」(ピリオド)一文字を表現している。「.」はパターンを表す書式に使用されるため、それを避けるために前に「¥」を付けている。この付けた「¥」自体もパターンを表す書式に使用する文字のため、「¥」の前にもさらに「¥」を付けている。
「[^¥¥.」+」とは、ピリオド以外の文字を一つ以上ということ。このように指定しないと、含まれるピリオドより右側すべての文字が削除されてしまう。
文字列から正規表現にマッチする文字列を抜き出す
str_extract関数を使う。str_match関数はその抜き出した文字列を分解して配列にして返す。マッチする文字列が無い場合はNAを返す。
以下は、郵便番号を表していると思われる文字列から、郵便番号の箇所のみ抜き出した例。正規表現では、「3桁の数字」+「「-」か何も無し」+「4桁の数字」からなる文字列を郵便番号と仮定して、抜き出している。str_match関数はマッチした内容を分解して表形式にして返す。
> s <- c("123-4567", "〒123-4567", "1234567", "123@4567", " 123-4567 ")
> str_extract(s, "([0-9]{3})(-*)([0-9]{4})")
[1] "123-4567" "123-4567" "1234567" NA "123-4567"
> str_match(s, "([0-9]{3})(-*)([0-9]{4})")
[,1] [,2] [,3] [,4]
[1,] "123-4567" "123" "-" "4567"
[2,] "123-4567" "123" "-" "4567"
[3,] "1234567" "123" "" "4567"
[4,] NA NA NA NA
[5,] "123-4567" "123" "-" "4567"
正規表現を使用してファイル名を表す文字列から拡張子を消す
gsub関数を使う。1つ目の例は拡張子をすべて削除、2つ目の例は拡張子を一つだけ削除した例。
> s <- c("カナメ.バッカニア.txt", "フレイア.ヴィオン.txt")
> print(s)
[1] "カナメ.バッカニア.txt" "フレイア.ヴィオン.txt"
> gsub("\\..+$", "", s)
[1] "カナメ" "フレイア"
> gsub("\\.[^\\.]+$", "", s)
[1] "カナメ.バッカニア" "フレイア.ヴィオン"
正規表現を使用してファイル名を表す文字列から拡張子を抜き出す
1つ目の例では、最後の拡張子を1つだけ抜き出している。2つ目の例では、1つ以上の拡張子のすべてを抜き出している。
> s <- c("カナメ.バッカニア.txt", "フレイア.ヴィオン.txt")
> gsub("^.+\\.", "", s)
[1] "txt" "txt"
> gsub("^[^\\.]+\\.", "", s)
[1] "バッカニア.txt" "ヴィオン.txt"
正規表現を使用していずれかの文字列にマッチする文字列を抜き出す
|記号を使う。それぞれの文字列は( )(括弧)で囲む。
> name <- c("カナメ", "セナディア", "イレイナ")
> seiyu <- c("安野希世乃", "鈴木みのり", "本渡楓")
> grep("イ", name, value = TRUE)
[1] "イレイナ"
> grep("カ", name, value = TRUE)
[1] "カナメ"
> grep("(イ|カ)", name, value = TRUE)
[1] "カナメ" "イレイナ"
> grep("(カ|ナ)", name, value = TRUE)
[1] "カナメ" "セナディア" "イレイナ"
> grep("(カ|ナ$)", name, value = TRUE)
[1] "カナメ" "イレイナ"
パターンにマッチするか否かを論理値で返す
grepl関数を使う。grep関数はパターンにマッチする要素のインデックスを返すが、grepl関数はマッチする要素は真(TRUE)、マッチしない要素は偽(FALSE)を返す。
> s <- c("石見舞菜香", "鈴木みのり", "瀬戸麻沙美", "和多田美咲")
> grep("美", s)
[1] 3 4
> grep("美$", s)
[1] 3
> grepl("美", s)
[1] FALSE FALSE TRUE TRUE
> grepl("美$", s)
[1] FALSE FALSE TRUE FALSE
パターンにマッチするか否かを論理値で返す
stringrパッケージのstr_detect関数を使う。同じstringrパッケージのstr_which関数はパターンにマッチする要素のインデックスを返すが、str_detect関数はマッチする要素は真(TRUE)、マッチしない要素は偽(FALSE)を返す。機能としてはbaseパッケージのgrepl関数と同等。
> s <- c("石見舞菜香", "鈴木みのり", "瀬戸麻沙美", "和多田美咲")
> stringr::str_which(s, "美")
[1] 3 4
> stringr::str_which(s, "美$")
[1] 3
> stringr::str_detect(s, "美")
[1] FALSE FALSE TRUE TRUE
> stringr::str_detect(s, "美$")
[1] FALSE FALSE TRUE FALSE
> grepl("美$", s)
[1] FALSE FALSE TRUE FALSE