【问题标题】:Detecting and Removing Commas from only a portion of a string in a large list of strings (R)仅从大型字符串列表中的一部分字符串中检测和删除逗号 (R)
【发布时间】:2015-08-27 22:21:13
【问题描述】:

我有一个很大的字符串列表,列表中的每个项目都显示如下:

largeList<-
  c("\t\t\t73,Tuesday,08/23/2014,09:03PM,Data Transfer,KB,\"60 KB\",MSDG,AT,GPRR,,0.00",
    "\t\t\t74,Tuesday,08/23/2014,10:17PM,Data Transfer,KB,\"1,412 KB\",MSDG,AT,GPRR,,0.00",       
    "\t\t\t75,Wednesday,08/24/2014,12:08AM,Data Transfer,KB,\"2,589 KB\",MSDG,AT,GPRR,,0.00",          
    "\t\t\t76,Wednesday,08/24/2014,12:26PM,Data Transfer,KB,\"23,576 KB\",MSDG,AT,GPRR,,0.00",
    "\t\t\t85,Thursday,08/25/2014,05:17PM,Data Transfer,KB,\"78,088 KB\",MSDG,AT,GPRR,,0.00") 

我正在尝试使用

以逗号分隔数据
lapply(largeList, "strsplit",",")

但我遇到的问题是,虽然大多数值都小于 1000(如“\”60 KB\”),但有时会有较大的值在其中包含一个逗号(如“23,576 KB\")。我试过了

grep('(["KB"])', test, value=TRUE)

只尝试找到模式,但所有不断发生的事情是返回整个字符串。我知道最终我会使用 gsub() 仅替换该部分,但我不知道该模式应该是什么。我能想出的最好的部分解决方案是使用 stringr 包:

str_locate_all(test, '([""])')

返回

[[1]]
     start end
[1,]    52  52
[2,]    62  62

上面示例列表的第5个值:

     [5] "\t\t\t85,Thursday,08/25/2014,05:17PM,Data Transfer,KB,\"78,088 KB\",MSDG,AT,GPRR,,0.00" 

据我了解,这确实针对我要更改的部分的开始和结束。但我觉得有一种更好的方法来操作字符串,我似乎无法弄清楚它的正则表达式。有人对此有更优雅的解决方案吗?

【问题讨论】:

  • 或许:lapply(largeList,strsplit,split="(?&lt;![0-9]),(?![0-9])",perl=T)
  • 试试gsub(".*?\"([^\"]+).*", "\\1", largeList)
  • 你到底想要什么?它只是传输/文件的大小(即 KB 之前的数字?还是忽略数字中的逗号的字符串拆分?
  • 顺便说一句,欢迎来到 SO,这是一个不错的开始。
  • 也许使用 find 而不是 split(如果 R 支持这些结构)(?:(?:^|,|\r?\n)\s*)(?:"([^"\\]*(?:\\[\S\s][^"\\]*)*)"(?:\s*(?:(?=,|\r?\n)|$))|([^,]*)(?:\s*(?:(?=,)|$)))

标签: regex r string


【解决方案1】:

也许可以为自己节省一个下午的正则表达式,并考虑read.csv()。由于您要查找的 KB 值在数据中被引号括起来,并且无论如何您都希望将其余数据拆分为逗号,这似乎是一个不错的选择。请注意以下栏V7

read.csv(text = largeList, header = FALSE, stringsAsFactors = FALSE)
#   V1        V2         V3      V4            V5 V6        V7   V8 V9  V10 V11 V12
# 1 73   Tuesday 08/23/2014 09:03PM Data Transfer KB     60 KB MSDG AT GPRR  NA   0
# 2 74   Tuesday 08/23/2014 10:17PM Data Transfer KB  1,412 KB MSDG AT GPRR  NA   0
# 3 75 Wednesday 08/24/2014 12:08AM Data Transfer KB  2,589 KB MSDG AT GPRR  NA   0
# 4 76 Wednesday 08/24/2014 12:26PM Data Transfer KB 23,576 KB MSDG AT GPRR  NA   0
# 5 85  Thursday 08/25/2014 05:17PM Data Transfer KB 78,088 KB MSDG AT GPRR  NA   0

仅提供您可以使用的 KB 值

read.csv(text = largeList, header = FALSE, stringsAsFactors = FALSE)[[7]]
# [1] "60 KB"     "1,412 KB"  "2,589 KB"  "23,576 KB" "78,088 KB"

此外,如果您需要在拆分数据中保留 0.00\t 等确切文本,您可以添加参数 colClasses = "character" 并删除 stringsAsFactors = FALSE。这样一来,数据看起来就和原来一样了,只是在相关的逗号上分开。

read.csv(text = largeList, header = FALSE, colClasses = "character")
#         V1        V2         V3      V4            V5 V6        V7   V8 V9  V10 V11  V12
# 1 \t\t\t73   Tuesday 08/23/2014 09:03PM Data Transfer KB     60 KB MSDG AT GPRR     0.00
# 2 \t\t\t74   Tuesday 08/23/2014 10:17PM Data Transfer KB  1,412 KB MSDG AT GPRR     0.00
# 3 \t\t\t75 Wednesday 08/24/2014 12:08AM Data Transfer KB  2,589 KB MSDG AT GPRR     0.00
# 4 \t\t\t76 Wednesday 08/24/2014 12:26PM Data Transfer KB 23,576 KB MSDG AT GPRR     0.00
# 5 \t\t\t85  Thursday 08/25/2014 05:17PM Data Transfer KB 78,088 KB MSDG AT GPRR     0.00
read.csv(text = largeList, header = FALSE, colClasses = "character")[[7]]
# [1] "60 KB"     "1,412 KB"  "2,589 KB"  "23,576 KB" "78,088 KB"

【讨论】:

  • 很好地重定向问题以更有效地解决问题。
  • 哇,这实际上正是我所需要的。谢谢!
  • @Tai0827 - 我认为它很接近。 Np,很乐意提供帮助。
【解决方案2】:

要获取双引号内的所有值,请使用

gsub("^[^\"]*\"([^\"]+).*", "\\1", largeList)

该模式匹配从字符串开头到第一个" 的除" 之外的0 个或多个字符,然后捕获双引号内的内容,并匹配其余内容。然后捕获的文本替换整个匹配。

IDEONE demo

【讨论】:

    【解决方案3】:
    Try:
    gsub('.*\"(.*)\".*','\\1',largeList)
    [1] "60 KB"     "1,412 KB"  "2,589 KB"  "23,576 KB" "78,088 KB"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-21
      • 2020-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-09
      相关资源
      最近更新 更多