以下是在 R 中使用基本 R (g)sub 和 stringr 删除/替换函数限制通用字符类的一些选项:
(g)sub 与 perl=TRUE
您可以将[[:punct:]] 括号表达式与[:punct:] POSIX 字符类一起使用,并使用(?!\.) 负前瞻来限制它,这将要求右侧紧随其后的字符不等于.:
(?!\.)[[:punct:]] # Excluding a dot only
(?![.-])[[:punct:]] # Excluding a dot and hyphen
要匹配一个或多个匹配项,请使用非捕获组对其进行包装,然后将+ 量词设置为该组:
(?:(?!\.)[[:punct:]])+ # Excluding a dot only
(?:(?![.-])[[:punct:]])+ # Excluding a dot and hyphen
请注意,当您删除找到匹配项时,两个表达式将产生相同的结果,但是,当您需要替换为其他字符串/字符时,量化将允许使用一次替换模式来更改整个连续的字符块。
带有stringr替换/删除功能
在详细介绍之前,请注意与 (g)sub 一起使用的 PCRE [[:punct:]] 不会匹配由 ICU regex library 提供支持的 stringr 正则表达式函数中的相同字符。您需要改用[\p{P}\p{S}],请参阅R/regex with stringi/ICU: why is a '+' considered a non-[:punct:] character?
ICU 正则表达式库有一个很好的功能,可以与字符类一起使用,称为 character class subtraction。
因此,您编写了您的字符类,例如所有标点匹配类,例如 [\p{P}\p{S}],然后您想要“排除”(=减去)一个字符或两个或三个字符,或者字符的整个子类。您可以使用两种表示法:
[\p{P}\p{S}&&[^.]] # Excluding a dot
[\p{P}\p{S}--[.]] # Excluding a dot
[\p{P}\p{S}&&[^.-]] # Excluding a dot and hyphen
[\p{P}\p{S}--[.-]] # Excluding a dot and hyphen
要使用这种方法匹配 1+ 个连续出现,您不需要任何包装组,只需使用 +:
[\p{P}\p{S}&&[^.]]+ # Excluding a dot
[\p{P}\p{S}--[.]]+ # Excluding a dot
[\p{P}\p{S}&&[^.-]]+ # Excluding a dot and hyphen
[\p{P}\p{S}--[.-]]+ # Excluding a dot and hyphen
见R demo tests with outputs:
x <- "Abc.123#&*xxx(x-y-z)???? some@other!chars."
gsub("(?!\\.)[[:punct:]]", "", x, perl=TRUE)
## => [1] "Abc.123xxxxyz someotherchars."
gsub("(?!\\.)[[:punct:]]", "~", x, perl=TRUE)
## => [1] "Abc.123~~~xxx~x~y~z~~~~~ some~other~chars."
gsub("(?:(?!\\.)[[:punct:]])+", "~", x, perl=TRUE)
## => [1] "Abc.123~xxx~x~y~z~ some~other~chars."
library(stringr)
stringr::str_remove_all(x, "[\\p{P}\\p{S}&&[^.]]") # Same as "[\\p{P}\\p{S}--[.]]"
## => [1] "Abc.123xxxxyz someotherchars."
stringr::str_replace_all(x, "[\\p{P}\\p{S}&&[^.]]", "~")
## => [1] "Abc.123~~~xxx~x~y~z~~~~~ some~other~chars."
stringr::str_replace_all(x, "[\\p{P}\\p{S}&&[^.]]+", "~") # Same as "[\\p{P}\\p{S}--[.]]+"
## => [1] "Abc.123~xxx~x~y~z~ some~other~chars."