cucumber flesh

Rを中心としたデータ分析・統計解析らへんの話題をしていくだけ

⭐️Rで絵文字の正規表現パターン

f:id:u_ribo:20160112215349p:plain

前から気になっていたのだが、ついカッとなって少し調べてみたら深みにはまってしまった。Rで絵文字の正規表現を実行する方法を整理してみる。

🉑 マッチするパターン

grep(pattern = "\xF0\x9F\x98\x81", "😁")
## [1] 1
grep(pattern = "\U0001f601", x = "絵文字だよ 😁", value = TRUE)
## [1] "絵文字だよ \U0001f601"

途中の0は省略しても良い 🙆

grepl(pattern = "\U1f601", x = "絵文字だよ 😁")
## [1] TRUE

enc2utf8()関数でバイト表記からUnicodeに変換することもできる。

enc2utf8("\xF0\x9F\x98\x81")
## [1] "\U0001f601"
grepl(enc2utf8("\xF0\x9F\x98\x81"), "絵文字だよ 😁")
## [1] TRUE
grep(enc2utf8("\xF0\x9F\x98\x81"), "😁", value = TRUE)
## [1] "\U0001f601"

文字集合による絵文字の正規表現マッチング

ではすべての絵文字を網羅するための文字集合はどう指定すれば良いか ❓

grepl("[\U0001F600-\U0001F64F]", c("😁", "🐳", "😄"))
## [1]  TRUE FALSE  TRUE

上記の例では顔文字は該当するが鯨の絵文字はマッチしていないので不十分 🙅。iPhoneGitHubを始めとした各種ウェブサービスで使われる(普及している絵文字を含んだ)Unicode 6.0をカバーするには次のような正規表現で抽出する。

# v6.0
grepl("[\U0001F0CF-\U000207BF]", c("😁", "🐳", "😄"))
## [1] TRUE TRUE TRUE

Unicode 6.0以降に登録された絵文字についても、各バージョンのUnicodeをもとに同様にマッチングできる。以前に http://rpubs.com/uri-sy/emoji_tableUnicodeのバージョンを絵文字のリストを作成したものがあるので、それを参考にしてそれぞれのバージョンで最小値と最大値を指定すれば良い 🙆

# v7.0
grepl("[\U0001F321-\U000203FA]", c("🛳", "🏌", "🌡"))
## [1] TRUE TRUE TRUE
# v8.0
grepl("[\U0001F32D-\U0001F9C0]", c("🤖", "🌭", "🦄"))
## [1] TRUE TRUE TRUE

また、絵文字にはより簡易な記号(ハートとか星とか)やグリフやらも含まれるのでそれらもマッチに含めるとこのようになる...はず。

remoji::emoji(list_emoji(), TRUE) %>% min()
## [1] "〰️ "
# 結果は省略。
#   すべてTRUEにならないのは同じ絵文字でも複数のunicodeが指定されているものがあるためか
grepl("[\U000270A-\U0001F9C0]", remoji::emoji(list_emoji(), TRUE))

おまけ

as.hexmode()関数を使ってas.numeric()で数値化するパターン。

as.hexmode("0001F1FC") %>% {
  print(.)
  as.numeric(.)
}
## [1] "1f1fc"

## [1] 127484

絵文字の挙動は面白い。

# print()では絵文字を出力することはできない
print("😁")

# message()とcat()関数はコンソール上に絵文字を「絵文字」として出力する
cat("😁")
message("😁")

x <- "\xF0\x9F\x98\x81"
cat(x)

enc2utf8("\U001F32D") %>% cat()

enjoy 😊