如何找到字符串中的最后一组数字

How do I find the last set of digits in a string

假设我有一个字符串

"Happy 2022 New 01 years!"

我正在寻找 return“01”。 更具体地说,我需要字符串中的最后一组数字。这个数字可能只是“1”、“10”或“999”…… 否则字符串几乎可以是任何东西。 我用 gsub 尝试了各种正则表达式,但似乎无法恰到好处。有一点我误解了。

例如,如果我这样做:

gsub('.*(\d+).*$', '\1', x)

那为什么我返回“1”呢?正则表达式中的“+”是否未指定一位或多位数字?

我的解释怎么错了?: '.' 用于任何字符,'(\\d+)' 用于一个或多个数字,'.'for some more characters, '$' 在字符串末尾。 gsub 是贪婪的,所以它将 return 最后一组数字(因此是 '01',而不是 '2022')。 '\\1' 将用第一个且唯一的匹配项替换整个字符串。 x 是字符串。

在目标最终数字周围放置单词边界:

x <- "Happy 2022 New 01 years!"
num <- gsub('.*\b(\d+)\b.*$', '\1', x)
num

[1] "01"

这里的挑战是我们很想使用惰性点在第一个数字处停止,例如.*?(\d+).*。但问题是现在我们将停在第一个数字,尽管我们想要最后一个。所以,贪心点是合适的,单词边界强制正则表达式捕获整个最终数字。

在您的正则表达式中,.* 将匹配所有字符(换行符除外),因此匹配整个字符串。然后,引擎尝试匹配 \d+ 但字符串中没有更多字符可匹配。因此,回溯发生在 .* 中,直到找到一个数字。一旦找到一个数字(即 1 在您的情况下),\d+ 匹配该数字并且字符串的其余部分再次与 .*.

匹配

你可以试试这个正则表达式:

\d+(?![^\r\n\d]*\d)

Click for Demo

解释:

  • \d+ - 匹配 1 个或多个数字,尽可能多
  • (?![^\r\n\d]*\d) - 否定前瞻以确保字符串后面没有更多数字

这可行:

(\d+)[^\d]*$

https://regex101.com/r/DHrttA/1

在你的解决方案中,我认为问题是第一个 .* 是贪婪的,所以它会尽可能地跳过。

使用 strsplit

的解决方法
> tail(strsplit(x, "\D+")[[1]], 1)
[1] "01"