我有一个这样的字符串:
foo > bar > foo bar > foo > test > test this
我想在大于符号的范围内取任何字符串并将它们转换为单个字,但它们之间没有空格但保留所有其他空格如下:
foo > bar > foobar > foo > test > testthis
我已尝试使用gsub删除空格gsub(" ", "", x, fixed = TRUE)
,但我不确定如何仅在大于标记的情况下执行此操作,同时保留大于标记旁边的空格
答案 0 :(得分:4)
一个选项是PCRE SKIP/FAIL
,匹配零个或多个空格(\\s*
),后跟>
后跟零个或多个空格(\\s*
)。在(*SKIP)
,它不再回到比赛的右侧,也不会重试。 (*FAIL)
强制模式为FAIL,直到(* SKIP)的左侧与(|\\s+
)右侧的空格字符((*FAIL)
)匹配,并将其替换为空白({{ 1}})
""
或另一种选择是匹配两个单词字符之间的空格。这里的空格在正正则表达式后瞻性单词字符(gsub("\\s*\\>\\s*(*SKIP)(*FAIL)|\\s+", "", str1, perl = TRUE)
#[1] "foo > bar > foobar > foo > test > testthis"
)和正向前瞻性单词字符之间或在字符串末尾((?<=\\w)
)
(?=\\w|\\$)
或者,如果不使用正则表达式,我们可以捕获单词
gsub("(?<=\\w)\\s(?=\\w|\\$)", "", str1, perl = TRUE)
#[1] "foo > bar > foobar > foo > test > testthis"
gsub("(\\w)\\s(\\w)", "\\1\\2", str1)
#[1] "foo > bar > foobar > foo > test > testthis"
答案 1 :(得分:1)
您可以使用匹配的模式和捕获 >
来实现您想要的内容,这些模式用空格(使用(\s*>\s*)
)并匹配而不捕获所有其他1个以上的空白块(\s+
) - 使模式工作所需的只是替换为第1组值的反向引用(\1
):
gsub("(\\s*>\\s*)|\\s+", "\\1", x)
或者,考虑到Unicode字符串,
gsub("(*UCP)(\\s*>\\s*)|\\s+", "\\1", x, perl=TRUE)
请参阅regex demo。
<强>详情
(\s*>\s*)
- 捕获第1组:0 +空格,>
,0 +空格|
- 或\s+
- 1+空白字符。请参阅R demo online:
x <- "foo > bar > foo bar > foo > test > test this"
gsub("(\\s*>\\s*)|\\s+", "\\1", x)
## => [1] "foo > bar > foobar > foo > test > testthis"
答案 2 :(得分:0)
对于非正则表达专家来说,这是一个(可以说是)更易处理的解决方案:
# Split into parts
str2 <- unlist(strsplit(str1, ">"))
str2
[1] "foo " " bar " " foo bar " " foo " " test " " test this"
# Eliminate all spaces
str3 <- gsub(" ", "", str2)
str3
[1] "foo" "bar" "foobar" "foo" "test" "testthis"
# And now paste again together
str_final <- paste(str3, collapse = " > ")
str_final
[1] "foo > bar > foobar > foo > test > testthis"