我正在尝试使用gsub
函数在所有单词周围放置单引号,除非单词" one"。我已经尝试了以下但是它没有像我预期的那样工作。
text <- "one two three four five one six one seven one eight nine ten one"
gsub("(?<!one)([a-zA-Z]+)", "'\\1'", text)
输出应为:
one 'two' 'three' 'four' 'five' one 'six' one 'seven' one 'eight' 'nine' 'ten' one
感谢任何帮助。
答案 0 :(得分:2)
对于初学者,(?<!...)
是 PCRE ,其中需要启用perl = TRUE
参数。
诀窍是在这里使用lookahead而不是lookbehind并添加word boundaries来强制正则表达式引擎匹配整个单词。另外,你大致说明了单词;在我的词汇表中,这可能意味着任何类型的单词,所以我将使用Unicode属性\pL
,它匹配来自任何语言的任何类型的字母,如果这匹配超过预期,您可以简单地将其更改回{{ 1}}或者使用名为class [a-zA-Z]
的POSIX代替。
[[:alpha:]]
答案 1 :(得分:1)
您可以尝试下面的PCRE正则表达式
> gsub('\\bone\\b(*SKIP)(*F)|([A-Za-z]+)', "'\\1'", text, perl=TRUE)
[1] "one 'two' 'three' 'four' 'five' one 'six' one 'seven' one 'eight' 'nine' 'ten' one"
\\bone\\b
与文字one
匹配,以下(*SKIP)(*F)
会使匹配跳过然后失败。现在它使用|
运算符右侧的模式从剩余的字符串中选择字符(即,跳过的部分除外)
答案 2 :(得分:1)
这是一种分步进行的方法。首先引用每个单词,然后从你不想引用的单词中删除引号。它可能会解决您的需求,但可能需要对标点符号进行一些额外的微调。
test <- paste0("'", text, "'")
test <- gsub(" ", "' '", test)
test <- gsub("'one'", "one", test)
答案 3 :(得分:1)
使用正则表达式似乎很奇怪。如果你有更复杂的表达式,也许这样的东西会起作用(并且会更具可读性)。
# for piping and equals() and not()
library(magrittr)
#helper function
partialswap <- function(x, criteria, transform) {
idx<-criteria(x)
x[idx]<-transform(x[idx])
x
}
not_equals <- function(x) . %>% equals(x) %>% not
is_not_in <- function(x) . %>% is_in(x) %>% not
text <- "one two three four five one six one seven one eight nine ten one"
strsplit(text, " ")[[1]] %>%
partialswap(not_equals("one"), shQuote) %>%
paste(collapse=" ")
# [1] "one 'two' 'three' 'four' 'five' one 'six' one 'seven' one 'eight' 'nine' 'ten' one"
或者,如果你想离开&#34;一个&#34;和&#34;三&#34;
strsplit(text, " ")[[1]] %>%
partialswap(is_not_in(c("one","three")), shQuote) %>%
paste(collapse=" ")
# [1] "one 'two' three 'four' 'five' one 'six' one 'seven' one 'eight' 'nine' 'ten' one"