如何使用 R 中的正则表达式删除字符串中表情符号的 Unicode 表示?

How to remove Unicode representations of Emojis in strings using regexp in R?

我正在处理来自 Twitter API 的数据,只要用户在其名称字段中包含表情符号,它们就会在我的数据框中转换为 Unicode 字符串表示形式。我的数据结构有点像这样:

user_profiles <- as.data.frame(c("Susanne Bold", "Julian K. Peard <U+0001F41C>", 
"<U+0001F30A> Alexander K Miller <U+0001F30A>", "John Mason"))
colnames(user_profiles) <- "name"

看起来像这样:

                                          name
1                                 Susanne Bold
2                 Julian K. Peard <U+0001F41C>
3 <U+0001F30A> Alexander K Miller <U+0001F30A>
4                                   John Mason

我现在正尝试使用正则表达式将实际名称隔离到一个新列中:

user_profiles <- user_profiles %>%
  mutate(clean_name = str_remove_all(name, "\<U\+[[:alnum:]]\>[ ]?"))

但是这个表达式 1. 看起来相当复杂并且 2. 不适用于识别模式。我已经尝试了正则表达式的多种变体,奇怪的是,grepl 能够检测到此版本的模式(string_remove_all 不接受,因为它缺少右括号):

grepl("\<U\+[[:alnum:]\>[ ]?", user_profiles$name)
[1] FALSE  TRUE  TRUE FALSE
# note that the second bracket around alnum is left opened

有人可以解释一下或提供更简单的解决方案吗?

非常感谢!

这里有一个替代方法:

library(dplyr)
library(tidyr)

user_profiles %>% 
  separate_rows(name, sep = '\<|\>') %>% 
  filter(!str_detect(name, 'U+')) %>% 
  mutate(name = na_if(name, "")) %>% 
  na.omit()
  name                  
  <chr>                 
1 "Susanne Bold"        
2 "Julian K. Peard "    
3 " Alexander K Miller "
4 "John Mason" 

第一个 str_remove_all 不起作用,因为您错过了字母数字模式后的 + 量词。另外,请注意在 <U+ 之后仅使用十六进制字符,因此您可以使用更精确的 [:xdigit:] POSIX 字符 class 而不是 [:alnum:]。 =44=]

你可以使用

user_profiles <- user_profiles %>%
  mutate(clean_name = str_remove_all(name, "<U\+[[:xdigit:]]+>\s*"))

不要转义 <>,它们在任何正则表达式风格中都不是特殊的,并且在 TRE 正则表达式中,与没有 perl=TRUE 的基本正则表达式函数一起使用,\<\> 是单词边界。

图案详情

  • <U - <U 字符串
  • \+ - 文字 +
  • [[:xdigit:]]+ - 一个或多个十六进制字符
  • > - 一个 > 字符
  • \s* - 零个或多个白色spaces.

为什么 grepl 正则表达式有效 ?这很有趣,因为您省略了 ] 右括号表达式边界字符,并“破坏”了正则表达式以像这样匹配:

  • \<U\+ - 单词边界(在 TRE 中,\< 匹配 left-hand 单词边界)然后 U+ string
  • [[:alnum:]\>[ ]? - 这是一个可选的括号表达式,匹配集合中的一个或零个字符:
    • [:alnum:] - 任何字母数字字符
    • \ - 反斜杠(是的,因为在 TRE 正则表达式风格中,正则表达式转义序列按字面意思处理)
    • > - 一个 > 字符
    • [ - 一个 [ 字符
    • - 一个 space.

因此,它匹配 <U+0001F41C> 中的 <U+0,例如。

我们可以为 [[:alnum:]]

添加一个或多个 (+)
library(dplyr)
library(stringr)
user_profiles <- user_profiles %>%
  mutate(clean_name = str_remove_all(name, "\s*\<U\+[[:alnum:]]+\>\s*")) 

-输出

user_profiles
                                      name         clean_name
1                                 Susanne Bold       Susanne Bold
2                 Julian K. Peard <U+0001F41C>    Julian K. Peard
3 <U+0001F30A> Alexander K Miller <U+0001F30A> Alexander K Miller
4                                   John Mason         John Mason