【问题标题】:find_replace nul character in R在R中find_replace nul字符
【发布时间】:2021-10-23 18:31:08
【问题描述】:

唯一与我的问题最接近的是:are-there-raw-strings-in-r 然而,这对我的帮助还不够。

问题

我在数据框中有类似 Windows 的格式化路径:

data.frame(path = c("X:\01_aim\01_seq.R", "X:\01_aim\02_seq.R", "X:\01_aim\03_seq.R"), 
           dat = c("data1.csv", "data2.csv", "data1.csv"))

目的是将路径转换为类 Unix 路径,因此我需要如下输出:

data.frame(path = c("/01_aim/01_seq.R", "/01_aim/02_seq.R", "/01_aim/03_seq.R"), 
           dat = c("data1.csv", "data2.csv", "data1.csv"))

我的方法

您在上面看到的一种操作路径的方法会产生以下错误:

> sub("\0", "##", "X:\01_aim\01_seq.R")
# Error: nul character not allowed (line 1)

我已经找到了使用r"()" 格式化选项打印路径的方法,它给出了:

> r"(X:\01_aim\01_seq.R)"
[1] "X:\01_aim\01_seq.R"

这样我的最终解决方案将接近:

tmp_path <- str_replace_all(string = r"(X:\01_aim\01_seq.R)",      
    pattern = r"(\\)", 
    replacement =  "/")
str_replace_all(tmp_path, r"(X:)", "")
[1] "/01_aim/01_seq.R"

但我缺乏的是如何在变量中的给定字符串上强制字符串的r"( )" 格式。具体来说,当我有一个功能时:

convert.path <- function(my.path){
   # how can I force the variable my.path to be stored as r"(`my.path`)"
   # so that I can insert the above code here.
   my.path.raw <- to.r.brackets(my.path)
   tmp_path <- str_replace_all(my.path.raw, pattern = r"(\\)", replacement =  "/")
   str_replace_all(tmp_path, r"(X:)", "")
}

我想强制重新格式化以代替 cmets。有谁知道如何制作这个技巧?

【问题讨论】:

  • 您的my.path 应该已经包含正确的字符串(= text)。否则,没有其他办法。除非有一些你没有解释的场景。
  • 也许您可以拆分路径并使用 R 的 file.path 函数?
  • 你的前提是错误的。 r"( )" 字符串的存储方式与其他字符串的存储方式没有区别。 r"( )" 格式只是在代码中指定字符串的一种方式。它使用与通常的" " 字符串不同的输入规则,但它生成和存储的内容与其他字符串没有区别。
  • @user2554330 好的,所以基本上没有办法让这段代码工作:my.path &lt;- "X:\01_aim\01_seq.R", sub("\0", "##", my.path) ?
  • 那不是法律代码。在常规字符串代码中,"\0" 表示空字符,而不是后跟零的反斜杠,并且 R 字符串中不允许使用空值。要编码您的路径,您应该使用"X:\\01_aim\\01_seq.R"。在sub() 中,情况更糟,因为您需要一个双反斜杠来匹配一个反斜杠,并且您需要"\\\\" 来编码两个反斜杠。所以sub() 应该是sub("\\\\0", "##", my.path)

标签: r regex string path formatting


【解决方案1】:

一种方法是在eval(parse(text = ...)) 中使用gsub()

dat <- data.frame(path = c("X:\01_aim\01_seq.R", "X:\01_aim\02_seq.R", "X:\01_aim\03_seq.R", "X:\01_aim\04_seq.R"), 
                  dat = c("data1.csv", "data2.csv", "data1.csv", "data2.csv"))

temp <- eval(parse(text= gsub("\\", "/", deparse(dat$path), fixed=TRUE)))
gsub("X:", "", temp)

#> [1] "/001_aim/001_seq.R" "/001_aim/002_seq.R" "/001_aim/003_seq.R"
#> [4] "/001_aim/004_seq.R"

reprex package (v2.0.1) 于 2021 年 8 月 23 日创建

另一种方法是使用stringi::stri_escape_unicode 转义包含一个反斜杠的字符串。由于字符串在转义之前转换为 unicode,因此在每对反斜杠之后添加了不需要的 u0。然后我们可以使用gsub("\\\\u0", "/") 来获取所需的文件路径。

dat <- data.frame(path = c("X:\01_aim\01_seq.R", "X:\01_aim\02_seq.R", "X:\01_aim\03_seq.R"), 
           dat = c("data1.csv", "data2.csv", "data1.csv"))


temp <- gsub("X:", "", stringi::stri_escape_unicode(dat$path))
gsub("\\\\u0", "/", temp)
#> [1] "/001_aim/001_seq.R" "/001_aim/002_seq.R" "/001_aim/003_seq.R"

reprex package (v2.0.1) 于 2021 年 8 月 23 日创建

【讨论】:

  • 亲爱的@TimTeaFan,对于"X:\000_aim\00_seq.R" 的情况,您有什么改进的方法吗?仍然有一个错误Error: nul character not allowed (line 1) 因为\000 我猜...编辑:还有"X:\A00_aim\00_seq.R" 失败。
  • @storaged:我添加了另一种方法,也许这适用于"X:\A00_aim\00_seq.R"。但是,由于此 R 代码是非法的,我什至无法将其放入 data.frame。我想知道这些字符串是从哪里来的?如果您在 csv 中读取,R 将自动将“X:\A00_aim\00_seq.R”转义为 "X:\\A00_aim\\00_seq.R"。你从哪里得到这些字符串?
猜你喜欢
  • 2016-03-16
  • 1970-01-01
  • 2015-04-11
  • 2023-02-25
  • 2014-08-18
  • 2013-10-20
  • 1970-01-01
  • 1970-01-01
  • 2013-03-04
相关资源
最近更新 更多