【问题标题】:R Extract partially matching stringR提取部分匹配的字符串
【发布时间】:2020-04-21 17:18:21
【问题描述】:

我有一个关于从具有这些行的多个文件中提取部分字符串的问题:

单位 = 指定 - 名称 0 = prDM:压力,Digiquartz [db] - 名称 1 = t090C:温度 [ITS-90,摄氏度] - 名称 2 = c0S/m:电导率 [S/m] - 名称 3 = t190C:温度,2 [ITS-90,摄氏度] - 名称 4 = c1S/m:电导率,2 [S/m] - 名称 5 = flSP:荧光,Seapoint - 名称 6 = sbeox0ML/L:氧气,SBE 43 [ml/l] - 名称 7 = altM:高度计 [m] - 名称 8 = sal00:盐度,实用 [PSU] - 名称 9 = sal11:盐度,实用,2 [PSU] - 跨度 0 = 1.000, 42.000

我只需要提取以“name”开头的列的信息,并提取 = 和: 之间的所有内容。 例如,在“名称 0 = prDM:压力,Digiquartz [db]”行中,所需的结果将是 prDM。 某些文件具有不同数量的“名称”行(即,此示例有 13 行,但其他文件有 16 行,并且数量会有所不同),所以我希望它尽可能通用,以便我总是可以独立提取正确的字符串行数。行以 # 开头,名称前有一个空格。 我试过这段代码,但它只提取第一行。你能帮我解决这个问题吗?非常感谢!

CNV<-NULL
for (i in 1:nro.files){
x <- readLines(all.files[i])
name.col<-grep("^\\# name", x) 
df <- data.table::fread(text = x[name.col])
CNV[[i]]<-df
}

【问题讨论】:

  • 我得到了这个错误:'\s' is an unrecognized escape in string started "" name[^=]+=\s"
  • 改用\\s。
  • 我做了但仍然只提取第一行...
  • 从str_match_all 提取所有匹配项后,您需要再创建一个for loop,如果您将从表中读取数据data.table::fread(text = x[result[[1]][[i,2]]])demo

标签: r regex


【解决方案1】:

使用stringr 和正则表达式模式"name \\d+ = (.*?):",这意味着“名称后跟一个或多个数字后跟等号后跟空格,后跟包含零个或多个字符(句点)的捕获组次(*)后跟冒号”。

   library(stringr)
    strings <- c("name 0 = prDM: Pressure, Digiquartz [db]",
    "name 1 = t090C: Temperature [ITS-90, deg C]",
    "name 2 = c0S/m: Conductivity [S/m]",
    "name 3 = t190C:Temperature, 2 [ITS-90, deg C]",
    "name 4 = c1S/m: Conductivity, 2 [S/m]",
    "name 5 = flSP: Fluorescence, Seapoint",
    "name 6 = sbeox0ML/L: Oxygen, SBE 43 [ml/l]",
    "name 7 = altM: Altimeter [m]",
    "name 8 = sal00: Salinity, Practical [PSU]",
    "name 9 = sal11: Salinity, Practical, 2 [PSU]")

    result <- str_match(strings, "name \\d+ = (.*):")
    result[,2]
 [1] "prDM"       "t090C"      "c0S/m"      "t190C"      "c1S/m"      "flSP"       "sbeox0ML/L"
 [8] "altM"       "sal00"      "sal11"

或者如果你喜欢base

pattern = "name \\d+ = (.*):"
result <- regmatches(strings, regexec(pattern, strings))
sapply(result, "[[", 2)

 [1] "prDM"       "t090C"      "c0S/m"      "t190C"      "c1S/m"      "flSP"       "sbeox0ML/L"
 [8] "altM"       "sal00"      "sal11" 

【讨论】:

  • 这很有用,谢谢!但我的问题是我有其他列有 = 和 : 但我只需要那些有字符串“name”后面跟一个数字的列
  • @CarlaBerghoff 我不确定您的问题是什么 - 请提供一个可重现的示例以及您每个 stackoverflow.com/questions/5963269/… 的预期输出如果您只需要确保原始字符串包含“名称”,您可以添加它到正则表达式result &lt;- str_match(strings, "name \\d = (.*):")
  • 这里以一个文件为例:dropbox.com/s/uq402dl22lingfo/CT01.cnv?dl=0
  • @CarlaBerghoff 请阅读我上面评论中链接帖子中的第一个答案,并制作一个类似于帖子描述的示例。
  • 它不起作用...我得到以“名称”开头的完整第一行并收到此警告:1:在 data.table::fread(text = x[result]) 中:已停止早在第 3 行。预期 2 个字段,但找到 1。考虑 fill=TRUE 和 comment.char=。第一个丢弃的非空行:>
【解决方案2】:

使用 stringr 包中的 str_extract 和正向前瞻和后向:

str <- "name 0 = prDM: Pressure, Digiquartz [db]"

str_extract(str, "(?<== ).*(?=:)")
[1] "prDM"

解释:

(?&lt;== )如果你看到=后跟左边的空白(向后看)

.* 匹配任何内容,直到 ...

(?=:)...您会在右侧看到一个冒号(前瞻)

【讨论】:

  • 由于其他列包含=和:,我只想提取以name开头的字符串,你能帮我调整一下代码吗?我太迷路了!谢谢!
  • 你能添加一些这些“其他”字符串的例子吗?
  • 如果我理解正确,您还有其他字符串也包含 = 和 :,但它们不以 name 开头,并且您不希望从中提取任何内容。--对?像这样的东西:str &lt;- c("name 0 = prDM: Pressure, Digiquartz [db]","blahblah X = blaBLah: blahblah usw.","name 1 = t090C: Temperature [ITS-90, deg C]")
【解决方案3】:

在基础R中

test <- c("name 0 = prDM: Pressure, Digiquartz [db]","name 1 = t090C: Temperature [ITS-90, deg C]")

gsub("^name [0-9]+ = (.+):.+","\\1",test)

[1] "prDM"  "t090C"

解释

^name [0-9]+ 搜索字符串 ^ 的开头,名称后跟任意长度的数字

= (.+): 任意长度 + 的任意字符 . 在 = 和 : 之间被存储 ( ) 以供以后由 \\1 调用

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-10
    • 1970-01-01
    • 1970-01-01
    • 2016-10-18
    • 1970-01-01
    • 2014-07-20
    • 2017-04-11
    相关资源
    最近更新 更多