【问题标题】:R gsub/str_replace to return a backslashR gsub/str_replace 返回一个反斜杠
【发布时间】:2019-03-31 19:11:42
【问题描述】:

我需要在 SQL 数据库中插入一个数据框。我已经构建了脚本(使用循环、str_c、RODBC)将我的数据框转换为 SQL 插入命令,但是我遇到了一个问题,即一个“'”破坏了 SQL。

这是一个问题的例子:

数据框如下所示:

pk  b
1    o'keefe

所需的 SQL 输出为:INSERT INTO table (pk, b) (1, 'o\'keefe')

gsub("'", "\'", str_replace_na(df$b[1], ""))

[1] "o'keefe"

gsub("'", "\\\\'", str_replace_na(df$b[1], ""))

[1] "o\\'keefe"

我试过str_replacestr_replace_all、gsub w/fixed = TRUEperl = TRUE,我得到了相同的结果。

我知道How to give Backslash as replacement in R string replace 上的评论指出cat() 显示斜线。但这不会延续到我的数据框或 SQL 查询中。

对于这个问题的任何帮助将不胜感激!


附加说明,我知道 R 会打印一个双反斜杠,如 http://r.789695.n4.nabble.com/gsub-replacing-double-backslashes-with-single-backslash-td4453328.htmlR: How to replace space (' ') in string with a *single* backslash and space ('\ ') 所引用,即使只有一个斜杠确实存在。但是,当出现零个或两个反斜杠时,我的 SQL 语句仍然无法工作。

【问题讨论】:

  • 标准 SQL 要求您将单引号内的单引号加倍。 C 风格的反斜杠不是标准 SQL 的一部分(尽管您正在使用但未提及的数据库可能支持它作为标准 SQL 的扩展)..
  • 很遗憾我没有使用标准 SQL,我使用的是 FileMaker Pro 的 SQL,它需要一个单引号。 (参见fmhelp.filemaker.com/docs/13/en/fm13_sql_reference.pdf,第 18 页)。

标签: r regex dplyr


【解决方案1】:

"o\\'keefe" 实际上是您想要的:双黑斜线实际上是单个反斜线的表示。

例如:

\U005C 是反斜杠的 unicode 字符。然而:

"\U005C"

[1] "\\"

而 \U002F 是正斜杠的 unicode 字符,并且:

"\U002F"

[1] "/"

所以你的第二个解决方案已经给了你想要的。删除不必要的str_replace_na()

gsub("'", "\\\\'", df$b[1])

[1] "o\\'keefe"

注意:实际上归功于@Rui Barradas,他证明了双反斜杠代表单个反斜杠:

nchar("\\")

[1] 1

【讨论】:

    【解决方案2】:

    尝试将单引号放在 ['] 中。

    x <- "o'keefe"
    y <- gsub("[']", "\\\\'", s)
    y
    #[1] "o\\'keefe"
    

    这似乎在字符串中添加了两个字符,但没有,只有一个\

    nchar(x)
    #[1] 7
    
    nchar(y)
    #[1] 8
    

    【讨论】:

    • 没有方括号你会得到相同的结果。 nchar(gsub("'", "\\\\'", df$b[1])) 也是 8
    • 所以我认为你有一个观点,即 OP 的第二个结果(显示 2 \ 而不是一个)实际上可能很好并且可以在 SQL 中工作。但是添加的括号是不必要的。在这种情况下,gsub("'", "\\\\'", df$b[1]) 就足够了。
    • @prosoitos 你说得对,方括号只需要元字符(和fixed = FALSE,R 默认值)。
    • 我不使用 SQL,所以我无法测试双 \ 实际上是否只有一个,但除了你聪明的 nchar() 测试之外,我尝试运行 "\U005C" 和它确实给了[1] "\\"(例如,"\U002F" 给了[1] "/"):) 所以你肯定是对的:)。所以答案是 OP 在他的第二次尝试中已经找到了解决方案(除了 str_replace_na() 是不必要的)。
    • @prosoitos 如果你发布它,我会删除我的。
    猜你喜欢
    • 2015-02-14
    • 2020-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多