我正在尝试编写一个正则表达式,用NA
替换所有不包含*
的值。有人能解释一下如何正确否定R风格(PCRE?)正则表达式中的转义符吗?
temp<-data.frame(c("hi","keep**",NA),c("keep***",NA,"xxx"))
lapply(temp,function(x){gsub("[^\*]",NA,x)}) #This did not work like I thought it would
目标
NA keep***
keep* NA
NA NA
主要问题似乎是只将一个不是星号的字符与[^\*]
匹配,并使用gsub
将其替换为NA
,而需要替换整个值(=字符串)。
使用^[^*]*$
:
^
-字符串的开头[^*]*
-匹配0+个不是*
的字符(由于末尾有*
量词)([^...]
是一个否定字符类,它匹配该类中定义的字符以外的所有字符)$
—字符串结束
由于正则表达式在没有perl=T
的gsub
中使用,因此不能在字符类中使用转义字符,因此TRE(源自POSIX)正则表达式风格禁止使用转义字符。
当您生成第一个字符"^"时,字符类运算符允许否定,但由于"裸"NA不是字符值,这还不够。您不需要转义字符类序列中的大多数其他特殊字符。你需要一个不同的策略来有条件地使选定的项目不适用。首先,你有一个伪装的因素混乱。我认为ifelse
是一个不错的策略。R自动地将字符值转换为各种因素,这些因素会导致混乱。使用字符串AsFactors=FALSE或lapply(dfrm, as.character)
来避免或修复:
> temp<-data.frame(a=c("hi","keep**",NA),b=c("keep***",NA,"xxx"), stringsAsFactors=FALSE)
> lapply(temp,function(x){ifelse( !grepl("[*]",x) , NA, x)})
$a
[1] NA "keep**" NA
$b
[1] "keep***" NA NA
不是最好的,但这也适用于
temp<-data.frame(c("hi","keep**",NA),c("keep***",NA,"xxx"))
lapply(temp,function(x){gsub("(?!.*\*)(\w+)", NA, x, perl=T)})