【问题标题】:R place quotes around all words except a certain oneR在除某个单词之外的所有单词周围加上引号
【发布时间】:2015-03-22 05:38:25
【问题描述】:

我正在尝试使用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

感谢任何帮助。

【问题讨论】:

  • 一个是“那个”似乎很讽刺

标签: regex r replace regex-lookarounds


【解决方案1】:

对于初学者,(?&lt;!...)PCRE,其中需要启用 perl = TRUE 参数。

诀窍是在这里使用lookahead 而不是lookbehind 并添加word boundaries 以强制正则表达式引擎匹配整个单词。此外,您广泛地陈述了单词;在我的词汇表中,这可能意味着任何类型的单词,所以我将使用 Unicode 属性 \pL,它匹配来自任何语言的任何类型的字母,如果匹配超出预期,您可以简单地将其更改回 [a-zA-Z] 或请改用 POSIX 命名类 [[:alpha:]]

gsub("(?i)\\b(?!one)(\\pL+)\\b", "'\\1'", text, perl=T)
# [1] "one 'two' 'three' 'four' 'five' one 'six' one 'seven' one 'eight' 'nine' 'ten' one"

【讨论】:

    【解决方案2】:

    这是一种分步执行的方法。首先引用每个单词,然后从您不想引用的单词中删除引号。它可能会解决您的需要,但可能需要对标点进行一些额外的微调。

    test <- paste0("'", text, "'")
    test <- gsub(" ", "' '", test)
    test <- gsub("'one'", "one", test)
    

    【讨论】:

      【解决方案3】:

      你可以试试下面的 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) 使匹配跳过然后失败。现在它使用| 运算符右侧的模式从剩余的字符串中选择字符(即,除了跳过的部分)

      DEMO

      【讨论】:

        【解决方案4】:

        使用正则表达式似乎很奇怪。如果您有更复杂的表达式,也许这样的东西会起作用(并且更具可读性)。

        # 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"
        

        或者如果你想省略“一”和“三”

        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"
        

        【讨论】:

        • 正则表达式看起来很神秘而且可能更快。
        • 当然这不会更快。但是,如果您既不想逃避“一”也不想逃避“三”呢?然后正则表达式会开始变得更加丑陋。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-29
        • 2020-06-04
        相关资源
        最近更新 更多