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

时间:2017-04-08 13:04:22

标签: r regex string utf-8 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字符。

有什么解决方法吗?

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

2 个答案:

答案 0 :(得分:9)

您可以使用课程[: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 "

或者,如果你想找到一个字符串,甚至不用空格绑定,请使用单词boundary \\b代替:

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

这里会发生什么:

  • .*?适合任何(。)至少0次(*)但不合适(?)。这意味着gsub将尝试通过这件作品填充尽可能少的数量。
  • ()之间的所有内容都将被存储,并且可以通过\\1
  • 替换为\\b
  • A-z表示字边界
  • 至少跟随A-Z,a-z,0-9或空格的任何字符一次(+)。你必须这样做,因为特殊字母包含在代码表中的大写和小写之间。所以使用\\1将包括所有特殊字母(UTF-8顺便提一下!)
  • 在该序列之后,适合任何至少零次以删除其余字符串。
  • 在正则表达式中结合.*的反向引用<pre>*you can use a while loop with a counter variable for simplicity* /int main() { string name; int num,age,cls; cout <<"Enter your name: "; cin>>name; cout <<"Enter your number: "; cin>>num; cout<<"Enter your age: "; cin>>age; cout <<"Enter your class: "; cin>>cls; int choice,k=1; while(k>0) { cout<<"\tPlease choose an option: "<<endl; cout <<"1. Display my name\n2. Display my number\n3. Display my age\n4. Display my class"<<endl; cin>>choice; switch (choice){ case 1: cout<<"Your name is :"<<name; break; case 2: cout <<"Your number is: "<<num; break; case 3: cout <<"Your age is: "<<age; break; case 4: cout <<"Your class is: "<<cls; break; default: cout <<"Invalid option!"; break; } cout<<("do you want to renter the details and run again:\n"); cout<<("enter 1 for yes and o for no"); cin>>k; } return 0; } 将确保只有所需部分保留在输出中。

答案 1 :(得分:0)

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

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

结果 [1]“+此处的样本字符串= {&gt; EBHP&lt;] {&gt;”