只使用gsub保留字符串中的字母数字字符和空格

问题描述:

我有一个包含字母数字字符,特殊字符和非UTF-8字符的字符串。我想剥离特殊和非UTF-8字符。只使用gsub保留字符串中的字母数字字符和空格

这是我已经试过:

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字符。

任何解决方法?

对于上面的样本串,输出应该是: 样本串这里

+0

您是否打算获得'trimws(gsub('[^ 0-9A-Za-z]','','ï¿+ +这里的示例字符串=�{�>Eï¿ ½BHï½P“))' – akrun

+1

'[^ A-z0-9]'更简洁@akrun。然而,这留下“样本字符串在这里EBHP”“ – zacdav

+3

'[AZ]'不仅字母匹配。 –

你可以使用的类[: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" 

这里会发生什么:

  • .*?适合任何事情LEA(。) st 0次(*),但未理解(?)。这意味着gsub会尝试尽可能适合这件作品。
  • ()之间一切将被存储,并且可以在替换由\\1
  • \\b可以refered到指示字边界
  • 这之后至少一次(+)由这是AZ,AZ,0-9任何字符或一个空间。您必须这样做,因为特殊字母包含在代码表中的大写和小写之间。所以使用A-z将包括所有特殊字母(它们是UTF-8 btw!)
  • 在该序列之后,适合任何东西至少零次以移除字符串的其余部分。
  • 反向引用\\1结合.*在正则表达式中,将确保只有所需的部分保留在输出中。
+0

添加'trimws()'完整性。请注意,这是完全可行的,因为字符串是由空格限定的,并且除非这是真的,否则将不能100%工作。 – zacdav

+0

@zacdav或只是不保留最终结果中的空格。 –

+1

@zacdav你对空格的评论是正确的,所以我添加了一个使用单词边界的例子。 –

stringr可以使用支持POSIX字符类一个differrent正则表达式引擎。 :ascii:命名类,它通常必须放在方括号[:asciii:]中,而方括号中的外方括号内。 [^表示否定匹配。

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

结果 [1] “+样本串此处= {> EBHP <] {>”