【问题标题】:R: How to replace space (' ') in string with a *single* backslash and space ('\ ')R:如何用*单*反斜杠和空格('\')替换字符串中的空格('')
【发布时间】:2016-12-18 22:33:09
【问题描述】:

我已经搜索了很多次,但在这里或其他地方都没有找到答案。我想用'\ ' 替换包含文件名的变量中的每个空格' '。 (一个用例可能是 shell 命令,其中空格已转义,因此每个文件名不会显示为参数列表。)我查看了 StackOverflow 问题"how to replace single backslash in R",发现许多组合确实像宣传的那样工作:

> gsub(" ", "\\\\", "a b")
[1] "a\\b"

> gsub(" ", "\\ ", "a b", fixed = TRUE)
[1] "a\\ b"

但尝试使用单斜杠版本,R 会忽略它:

> gsub(" ", "\\ ", "a b")
[1] "a b"

> gsub(" ", "\ ", "a b", fixed = TRUE)
[1] "a b"

对于反方向的情况——从字符串中删除斜线,它适用于两个:

> gsub("\\\\", " ", "a\\b")
[1] "a b"

> gsub("\\", " ", "a\\b", fixed = TRUE)
[1] "a b"

但是,对于单斜线,R 中的一些内在反常使我什至无法尝试删除它们:

> gsub("\\", " ", "a\\b")
Error in gsub("\\", " ", "a\\b") : 
  invalid regular expression '\', reason 'Trailing backslash'

> gsub("\", " ", "a\b", fixed = TRUE)
Error: unexpected string constant in "gsub("\", " ", ""

“无效的正则表达式”告诉我们一些事情,但我看不出是什么。 (还要注意perl = True 选项没有帮助。)

即使有三个反斜杠,R 也没有注意到一个:

> gsub(" ", "\\\ ", "a b")
[1] "a b"

模式也延伸了!甚至是两个的倍数:

> gsub(" ", "\\\\\\\\", "a b")
[1] "a\\\\b"

但不是奇数倍数(应该得到'\\\ ':

> gsub(" ", "\\\\\\ ", "a b")
[1] "a\\ b"

> gsub(" ", "\\\ ", "a b", fixed = TRUE)
[1] "a\\ b"

(我希望是 3 个斜杠,而不是两个。)

我的两个问题是:

  • 如何实现将' ' 替换为'\ ' 的目标?
  • 为什么替换的奇数斜线变体失败,而偶数斜线替换有效?

对于 shell 命令,一个简单的解决方法是引用文件名,但我的部分兴趣只是想了解 R 的正则表达式引擎发生了什么。

【问题讨论】:

  • 尝试cat() 获取一些结果 - \b 是退格字符,例如 \n 是换行符,\t 是制表符。例如。 - cat("remove_one_letter_from_the_end\b") - 两个斜杠“\\”实际上是一个斜杠 - R 控制台只是添加了一个额外的斜杠来转义它。 cat("\\", sep="\n")
  • @thelatemail 你在我写到一半的时候发表了你的评论。
  • @TimBiegeleisen - 一切都好 - 我认为你已经涵盖了主要问题!
  • 一个好建议@thelatemail。很明显,如果不是全部的话,一些解释是在 print() 正在做的事情中。但是,如果我尝试cat(gsub(" ", "\\ ", "a z")),结果是"a z" 删除了换行符 - 但请注意 z 没有转义,字母之间的空格仍然存在......
  • @user3897315 - 它在gsub 内部变得更加复杂 - 因为斜线可用于为正则表达式中的空格指定\s 之类的东西,它需要有额外的转义,所以R 需要@ 987654346@ 代表一个空格。这意味着您实际上需要四个斜杠 "\\\\" 来表示一个斜杠,否则它将毫无意义 - cat(gsub(" ", "\\\\ ", "a z"))

标签: regex r replace


【解决方案1】:

准备好脸掌,因为:

> gsub(" ", "\\\ ", "a b", fixed = TRUE)
[1] "a\\ b"

确实有效。

您看到的两个反斜杠只是 R 控制台显示单个反斜杠的方式,在打印到屏幕时会被转义。

要确认用单个反斜杠替换确实有效,请尝试将输出写入文本文件并检查自己:

f <- file("C:\\output.txt")
writeLines(gsub(" ", "\\", "a b", fixed = TRUE), f)
close(f)

output.txt 中,您应该会看到以下内容:

a\b

【讨论】:

  • 我认为你不需要第三个斜线 - gsub(" ", "\\ ", "a b", fixed = TRUE) 应该足够了
  • 谢谢。对掌心说是;这是有道理的,现在我看到 R 的打印语句包括那些“有用的”转义反斜杠。我还不明白为什么在打印的输出中添加额外的反斜杠会有所帮助——Perl 和 python 都没有将它包含在显示的打印中——但是知道了这一点,我可以继续。
  • @user51462 fixed = TRUE 告诉 R 在替换时不要使用正则表达式引擎。相反,它将使用您传递给它的文字表达式。
  • 嗯...它确实只适用于第一个参数。
【解决方案2】:

非常有帮助的讨论! (我已经在谷歌上搜索了 2 天。)

查看差异的另一种方法(而不是写入文件)是使用printcat 比较字符串的内容。

z <- gsub(" ", "\\", "a b", fixed = TRUE)

> print(z)
[1] "a\\ b"

> cat(z)
a\ b

因此,通过使用cat 而不是print,我们可以确认gsub 行正在执行我们尝试向字符串添加单个反斜杠时的预期。

【讨论】:

  • 也许/理想情况下,base::shQuote 的未来版本可以为我们所有人简化/自动化这个过程?
猜你喜欢
  • 1970-01-01
  • 2023-03-24
  • 1970-01-01
  • 1970-01-01
  • 2014-04-02
  • 2016-01-12
  • 2017-05-02
  • 2012-09-19
  • 2021-12-29
相关资源
最近更新 更多