使用 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
与正则表达式中的 .*
相结合,将确保只有需要的部分保留在输出中。
我有一个包含字母数字字符、特殊字符和非 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
与正则表达式中的.*
相结合,将确保只有需要的部分保留在输出中。