使用 gsub 在字符串中仅保留字母数字字符和 space

keep only alphanumeric characters and space in a string using gsub

我有一个包含字母数字字符、特殊字符和非 UTF-8 字符的字符串。我想去除特殊字符和非 utf-8 字符。

这是我尝试过的方法:

gsub('[^0-9a-z\s]','',"�+ Sample string here =�{�>E�BH�P<]�{�>")

但是,这会删除特殊字符(标点符号 + 非 utf8),但输出没有空格。

gsub('/[^0-9a-z\s]/i','',"�+ Sample string here =�{�>E�BH�P<]�{�>")

结果中有空格,但仍然存在非 utf8 字符。

有解决办法吗?

对于上面的示例字符串,输出应该是: 示例字符串在这里

stringr 可能使用支持 POSIX 字符 classes 的不同正则表达式引擎。 :ascii: 命名 class,通常必须将其括在方括号 [:asciii:] 中,在外方括号内。 [^ 表示匹配项的否定。

library(stringr)
str_replace_all("�+ Sample string here =�{�>E�BH�P<]�{�>", "[^[:ascii:]]", "")

结果 [1] "+ 此处示例字符串 ={>EBHP<]{>"

您可以为此使用 类 [:alnum:][:space:]

sample_string <- "�+ Sample 2 string here =�{�>E�BH�P<]�{�>"
gsub("[^[:alnum:][:space:]]","",sample_string)
#> [1] "ï Sample 2 string here ïïEïBHïPïï"

或者您可以使用 PCRE 代码来引用特定的字符集:

gsub("[^\p{L}0-9\s]","",sample_string, perl = TRUE)
#> [1] "ï Sample 2 string here ïïEïBHïPïï"

这两种情况都清楚地说明了字符仍然存在,被认为是字母。另外 EBHP 里面仍然是字母,所以你替换的条件是不正确的。您不想保留所有字母,只想保留 A-Z、a-z 和 0-9:

gsub("[^A-Za-z0-9 ]","",sample_string)
#> [1] " Sample 2 string here EBHP"

这仍然包含 EBHP。如果你真的只想保留一个只包含字母和数字的部分,你应该使用相反的逻辑:select 你想要的并替换所有但使用反向引用的部分:

gsub(".*?([A-Za-z0-9 ]+)\s.*","\1", sample_string)
#> [1] " Sample 2 string here "

或者,如果你想查找一个字符串,即使没有被 spaces 约束,使用单词边界 \b 代替:

gsub(".*?(\b[A-Za-z0-9 ]+\b).*","\1", sample_string)
#> [1] "Sample 2 string here"

这里发生了什么:

  • .*? 适合任何东西 (.) 至少 0 次 (*) 但不贪心 (?)。这意味着 gsub 将尝试用这块来适应尽可能小的数量。
  • () 之间的所有内容都将被存储,并且可以在 \1
  • 的替换中引用
  • \b表示分词
  • 任何字符 A-Z、a-z、0-9 或 space 后至少跟一次 (+)。你必须这样做,因为特殊字母包含在代码 table 的大小写之间。所以使用 A-z 将包括所有特殊字母(顺便说一句,它们是 UTF-8!)
  • 在该序列之后,至少匹配任何内容零次以删除字符串的其余部分。
  • 反向引用 \1 与正则表达式中的 .* 相结合,将确保只有需要的部分保留在输出中。