我需要在R中编辑data.frame,其中一些变量是[xx xx xxx]格式的字符串。我试过gsub函数(失败了)。
示例:
aux = '1233,[9 087],03/10/1951,[437 ab 345] ,"ab c", [ 001 ab ]'
gsub("\\[(.*),(.*)\\]","[\\1 \\2]", aux)
目标:仅将括号数据之间的空格替换为逗号。
"1233,[9,087],03/10/1951,[437,ab,345] ,\"ab c\", [001,ab]"
...但是,上面gsub代码的结果是:
[1] "1233,[9 087],03/10/1951,[437 ab 345] ,\"ab c\", [ 001 ab,]"
请注意,空间的大小是不规则的。这个想法是将所有空格替换为括号“[]”到逗号“,”,除了第一个字符之前和之后的空格。
我该怎么做?
答案 0 :(得分:3)
假设您需要用逗号替换的空格中没有嵌套或其他方括号,您可以使用带有df <- read.table(text="Quantity SKU
1,1 2494008,2493953
1,1,1 2167550,1336380,2365409
3,2,1,6,1 1428608,1137956,2401393,2679310,2579183",header=TRUE,stringsAsFactors=FALSE)
library(tidyr)
df %>% separate_rows(Quantity,SKU)
Quantity SKU
<chr> <chr>
1 1 2494008
2 1 2493953
3 1 2167550
4 1 1336380
5 1 2365409
6 3 1428608
7 2 1137956
8 1 2401393
9 6 2679310
10 1 2579183
的PCRE正则表达式:
gsub
请参阅R demo和regex demo。
以下是解释:
aux = '1233,[9 087],03/10/1951,[437 ab 345] ,"ab c", [ 001 ab ]'
res = gsub("(?:\\G(?!^)|\\[\\s*)[^][\\s]*\\K\\s++(?!])(?=[^][]*])", ",", aux, perl=TRUE)
cat(res, "\n")
## => 1233,[9,087],03/10/1951,[437,ab,345] ,"ab c", [ 001,ab ]
- 上次成功匹配((?:\G(?!^)|\[\s*)
)或\G(?!\A)
以及零个或多个空格后的位置[
- 除[^][\s]*
,]
和空格之外的0个字符[
- 匹配重置运算符\K
- 占位符匹配的1个空格(没有回溯到模式中,只有在最后一个空格匹配后才会检查下一个否定前瞻)\s++
- 当前位置右侧必须没有(?!])
]
- 除了(?=[^][]*])
和[
之外必须有0个以上的字符,然后紧靠当前位置右侧的]
如果您考虑使用非基础R方法,我可以推荐]
:
gsubfn
此处,library(gsubfn)
rx <- "\\[([^][]+)]"
aux = '1233,[9 087],03/10/1951,[437 ab 345] ,"ab c", [ 001 ab ]'
gsubfn(rx, function(g1) paste0("[",gsub("\\s+", ",", trimws(g1)),"]"), aux)
## => [1] "1233,[9,087],03/10/1951,[437,ab,345] ,\"ab c\", [001,ab]"
匹配以\\[([^][]+)]
开头的子字符串,然后有{+ 1}}和[
以及[
以外的1个字符,并且找到匹配项,使用]
修剪第1组子值,并使用逗号(]
)替换所有1 +个空格块。
答案 1 :(得分:1)
分两步完成。
并且不如regex-master Wiktor的解决方案那么棒。
为简单起见,做出了一些假设。
\s
)\w
)aux = "1233,[9 087],03/10/1951,[437 ab 345] ,\"ab c\", [ 001 ab ]"
# remove the spaces after a "[" or before a "]"
result = gsub("(?<=\\[) +| +(?=\\])", "", aux, perl=TRUE)
# find a "[". Reset and look for spaces followed by word characters.
# And replace those matches by a comma and the word characters
result = gsub("(?:\\[ *\\w+\\K|\\G) +(\\w+)", ",\\1", result, perl=TRUE)
cat(result, "\n")
可以找到一个R-Fiddle here