【问题标题】:R: escape single quote for SQLite with gsub (avoiding double escaping already escaped strings)R:使用 gsub 转义 SQLite 的单引号(避免双重转义已经转义的字符串)
【发布时间】:2017-01-02 00:13:18
【问题描述】:

我需要转义文本字符串以将它们插入 SQLite 数据库。

问题出在我的管道中,我可能已经转义了字符串。我需要注意'' 的可能性。

例如,

string1 <- "On the Internet, nobody knows I'm a dog"
string2 <- "On the Internet, nobody knows I''m a dog"
gsub("'", "''", string1)
# [1] "On the Internet, nobody knows I''m a dog"

但是

gsub("'", "''", string2)
# [1] "On the Internet, nobody knows I''''m a dog"

还有

gsub("([^'])'[^']", "'", string2)
# "On the Internet, nobody knows I''m a dog"

但是

gsub("([^'])'[^']", "'", string1)
# [1] "On the Internet, nobody knows ' a dog"

【问题讨论】:

  • @hrbrmstr 其实我没有。
  • 这是一个混乱的业务,您可以通过使用 RODBCext 包的参数化查询来避免。

标签: r regex sqlite


【解决方案1】:

前瞻/后视是一种方法(也是更优化的方法),但您也可以更暴力一些(如果您愿意处理文本两次):

library(stringi)
library(magrittr)

txt_vals <- c("On the Internet, nobody knows I'm a dog's dog",
              "On the Internet, nobody knows I''m a dog's dog")

stringi::stri_replace_all_regex(txt_vals, "''", "'") %>% 
  stringi::stri_replace_all_regex("'", "''")

您应该接受第一个有效的前瞻/后视解决方案与这个解决方案,但同时这会让您继续前进。

【讨论】:

  • 这似乎只替换了第一次出现的引用:stringi::stri_replace_all_regex("On the Internet, nobody knows I'm a dog's dog", regex, "$1''$2") 返回"On the Internet, nobody knows I''m a dog's dog"
【解决方案2】:

用户 hrbmstr 提到的基于此正则表达式的正向后视解决方案:(?&lt;=')':

string1 <- "On the Internet, nobody knows I'm a dog"
string2 <- "On the Internet, nobody knows I''m a dog"
string3 <- "On the Internet, nobody knows I'm a dog's dog"
string4 <- "On the Internet, nobody knows I''m a dog''s dog"
string5 <- "Weird Al'''s apostrophes"
gsub("(?<=')'", "", string1, perl=TRUE)
gsub("(?<=')'", "", string2, perl=TRUE)
gsub("(?<=')'", "", string3, perl=TRUE)
gsub("(?<=')'", "", string4, perl=TRUE)
gsub("(?<=')'", "", string5, perl=TRUE)

输出:

"On the Internet, nobody knows I'm a dog"
"On the Internet, nobody knows I'm a dog"
"On the Internet, nobody knows I'm a dog's dog"
"On the Internet, nobody knows I'm a dog's dog"
"weird al's apostrophes"

【讨论】:

    【解决方案3】:

    虽然使用带有 RODBCext package 的参数化查询可以正常工作,但可以使用以下 PCRE 正则表达式实现仅用正则表达式替换奇数引号的解决方案:

    x <- c("On the Internet, nobody knows I'm a dog", "On the Internet, '''nobody''' knows I''m a ''''dog''''")
    gsub("''(*SKIP)(?!)|'", "''", x, perl=TRUE)
    ## 
    ## [1] "On the Internet, nobody knows I''m a dog"                
    ## [2] "On the Internet, ''''nobody'''' knows I''m a ''''dog''''"
    

    查看regex demoR demo

    详情

    • '' - 两个连续的单引号
    • (*SKIP)(?!) - 特殊的 PCRE 动词和负前瞻序列使正则表达式引擎跳过消耗的文本并从丢弃的文本末尾继续匹配
    • | - 或
    • ' - 单引号。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-05-03
      • 1970-01-01
      • 1970-01-01
      • 2013-01-06
      • 1970-01-01
      相关资源
      最近更新 更多