使用gsub函数在字符串中仅保留字母数字字符和空格。

15
我有一个字符串包含字母数字字符、特殊字符和非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 字符。

有什么解决方法吗?

对于上面的示例字符串,输出应为: Sample string here


你是不是想要获取 trimws(gsub('[^0-9A-Za-z ]','',"�+ Sample string here =�{�>E�BH�P<]�{�>")) - akrun
1
"[^A-z0-9 ]"更加简洁@akrun。然而,这会留下“Sample string here EBHP]”。 - zacdav
3
[A-z] 不仅匹配字母。 - Wiktor Stribiżew
2个回答

28

你可以使用类[: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。如果你只想保留一个仅包含字母和数字的部分,你应该使用相反的逻辑:选择你想要的内容并使用回溯引用替换除此之外的所有内容:

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

或者,如果您想查找一个字符串,即使它没有被空格包围,也可以使用单词边界\\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或空格字符。你必须这样做,因为特殊字母包含在代码表的大写和小写字母之间。所以使用 A-z 将包含所有特殊字母(它们还是UTF-8!)。
  • 在该序列之后,匹配任何字符,至少零次以删除剩余的字符串。
  • 正则表达式中的反向引用 \\1 结合 .* 确保只有所需部分保留在输出中。

为了完整性,添加 trimws()。请注意,这仅适用于由空格限定的字符串,并且除非该条件成立,否则不会百分之百地起作用。 - zacdav
@zacdav或者最终结果中不要保留空格。 - Joris Meys
1
@zacdav,你关于空格的评论是正确的,因此我添加了一个使用单词边界的示例。 - Joris Meys
我相信“单词边界”是所需的答案,很好。 - zacdav

0

stringr 可能使用不同的正则表达式引擎,支持 POSIX 字符类。:ascii: 命名了该类,通常必须在外部方括号中用方括号 [:asciii:] 括起来。[^ 表示匹配的否定。

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

结果为 [1] "+ 这里是示例字符串 ={>EBHP<]{>"


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接