假设我有一个字符串
"Happy 2022 New 01 years!"
我想把";01";。更具体地说,我需要字符串中的最后一组数字。这个数字可能只是"1"、"10"或"999"。。。否则,绳子几乎可以是任何东西。我用gsub尝试了各种正则表达式,但似乎都做不好。有件事我误解了。
例如,如果我这样做:
gsub('.*(\d+).*$', '\1', x)
那我为什么要回来;1〃;?正则表达式中的"+"是否未指定一个或多个数字?
我的解释怎么错了?:">'表示任何字符,'(\\d+('表示一个或多个数字,''对于更多的字符,在字符串末尾添加'$'。gsub是贪婪的,所以它将返回最后一组数字(因此是"01",而不是"2022"(\\1'将用第一个也是唯一一个匹配项替换整个字符串。x是字符串。
在正则表达式中,.*
将匹配所有字符(换行符除外(,从而匹配整个字符串。然后,引擎尝试匹配d+
,但字符串中已没有要匹配的字符。因此,在.*
中进行反向跟踪,直到找到一个数字。一旦找到一个数字(即,在您的情况下为1
(,d+
将与该数字匹配,字符串的其余部分将再次由.*
匹配。
你可以试试这个正则表达式:
d+(?![^rnd]*d)
点击演示
解释:
d+
-匹配1个或多个数字,尽可能多(?![^rnd]*d)
-负前瞻,以确保字符串后面不再有数字
在目标最终数字周围放置单词边界:
x <- "Happy 2022 New 01 years!"
num <- gsub('.*\b(\d+)\b.*$', '\1', x)
num
[1] "01"
这里的挑战是,我们很想使用一个懒惰的点来停止在第一个数字,例如.*?(\d+).*
。但问题是,现在我们将停留在第一个数字,尽管我们想要最后一个。因此,贪婪点是合适的,单词边界迫使正则表达式捕获整个最终数字。
这可以工作:
(d+)[^d]*$
https://regex101.com/r/DHrttA/1
在你的解决方案中,我认为问题是第一个.*
是贪婪的,所以它会跳过它所能跳过的。
使用strsplit
的解决方法
> tail(strsplit(x, "\D+")[[1]], 1)
[1] "01"