我试图删除除第一组数字之外的字符串中的所有数字。换句话说,所有重复的数字集,字符串中可能有1组或10多组,但我只想保留第一组和字符串的其余部分。
例如,以下字符串:
x <- 'foo123bar123baz123456abc1111def123456789'
结果将是:
foo123barbazabcdef
我尝试使用gsub
并用空字符串替换\d+
,但这会替换字符串中的所有数字,我也尝试使用组来捕获一些结果但没有运气。
答案 0 :(得分:7)
使用gsub,您可以使用\G
功能,这是一个可以在两个位置之一匹配的锚点。
x <- 'foo123bar123baz123456abc1111def123456789'
gsub('(?:\\d+|\\G(?<!^)\\D*)\\K\\d*', '', x, perl=T)
# [1] "foo123barbazabcdef"
<强>解释强>:
(?: # group, but do not capture:
\d+ # digits (0-9) (1 or more times)
| # OR
\G(?<!^) # contiguous to a precedent match, not at the start of the string
\D* # non-digits (all but 0-9) (0 or more times)
)\K # end of grouping and reset the match from the result
\d* # digits (0-9) (0 or more times)
或者,您可以使用可选组:
gsub('(?:^\\D*\\d+)?\\K\\d*', '', x, perl=T)
我觉得有用且不需要(*SKIP)(*F)
回溯动词或\G
和\K
功能的另一种方法是在上下文中使用alternation运算符放置您想要的内容匹配左侧的捕获组并将您要排除的内容放在右侧(说扔掉它,它是垃圾 ...)
gsub('^(\\D*\\d+)|\\d+', '\\1', x)
答案 1 :(得分:3)
您可以通过PCRE动词(*SKIP)(*F)
执行此操作。
^\D*\d+(*SKIP)(*F)|\d+
^\D*\d+
匹配从开头到第一个数字的所有字符。 (*SKIP)(*F)
导致匹配失败,然后正则表达式引擎尝试使用位于|
右侧的模式与剩余字符串\d+
匹配字符。由于(*SKIP)(*F)
是PCRE动词,因此您必须启用perl=TRUE
参数。
代码:
> x <- 'foo123bar123baz123456abc1111def123456789'
> gsub("^\\D*\\d+(*SKIP)(*F)|\\d+", "", x, perl=TRUE)
[1] "foo123barbazabcdef"