我重新格式化了一些字符向量,但格式化中存在一些我意外需要处理的异常。这是一个将重新格式化的字符串示例:
t <- "COZ009 - 013 - 016 - 018 034>036 - 039>040 - 066>081"
问题是这里缺少连字符“... 018 034&gt; 036 ......”。它应该是“...... 018-034> 036 ......”。
我想使用像gsub
之类的简单基函数添加连字符,但是如何在不触及所有其他空格的情况下替换缺少连字符的空格?那就是如何以周围的字符为条件进行替换?
我能提出的最接近的是。
t2 <- gsub(" - ", "-", t)
gsub(" ", "-", t2)
[1] "COZ009-013-016-018-034>036-039>040-066>081"
这个解决方案可能没什么问题,但知道如何有条件地更换会很好。
答案 0 :(得分:5)
您可以指定周围的字符是数字并使用捕获组,以便您不会删除它们。
gsub("(\\d)\\s+(\\d)", "\\1 - \\2", t)
[1] "COZ009 - 013 - 016 - 018 - 034>036 - 039>040 - 066>081"
这里围绕数字的括号将它们存储在变量\ 1&amp; \ 2,所以你可以避免改变它们。
答案 1 :(得分:2)
1)用空格,减号,空格替换字边界包围的任何空格:
gsub("\\b \\b", " - ", t)
## [1] "COZ009 - 013 - 016 - 018 - 034>036 - 039>040 - 066>081"
2)另一个简单的方法是用空格,减号,空格替换任何空格序列和减号:
gsub("[ -]+", " - ", t)
## [1] "COZ009 - 013 - 016 - 018 - 034>036 - 039>040 - 066>081"
2a)其中一个变体是使用strsplit
sapply(strsplit(t, "[ -]+"), paste, collapse = " - ")
## [1] "COZ009 - 013 - 016 - 018 - 034>036 - 039>040 - 066>081"
3)另一种可能性是用空格替换空格,减号,空格,然后用空格,减号,空格替换所有空格。
tmp <- gsub(" - ", " ", t)
gsub(" ", " - ", tmp)
## [1] "COZ009 - 013 - 016 - 018 034>036 - 039>040 - 066>081"
4)另一个简单的可能性是将空格,减号,空格替换为某些不会出现的字符,例如分号。然后用空格,减号,空格替换空格,然后将分号还原。在这种情况下(3)似乎相似但更简单,但如果你不得不用其他东西替换原始空间,那么这个可能比(3)更受欢迎。
tmp <- gsub(" - ", ";", t)
tmp <- gsub(" ", " - ", tmp)
gsub(";", " - ", t)
## [1] "COZ009 - 013 - 016 - 018 034>036 - 039>040 - 066>081"
更新:新增(1)并添加其他替代方案。
答案 2 :(得分:1)
@ G5W的答案有效 - 我修改代码只包含某些字符串长度:
> gsub("([[:digit:]]{1,3})[[:space:]]{1,2}([[:digit:]]{1,3})", "\\1 - \\2", p)
[1] "COZ009 - 013 - 016 - 018 - 034>036 - 039>040 - 066>081"
上面的代码专门针对前后字符串由1-3位数组成并且间隔不超过两个空格的模式。