如何找到字符串中的最后一组数字
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)
解释:
\d+
- 匹配 1 个或多个数字,尽可能多
(?![^\r\n\d]*\d)
- 否定前瞻以确保字符串后面没有更多数字
这可行:
(\d+)[^\d]*$
https://regex101.com/r/DHrttA/1
在你的解决方案中,我认为问题是第一个 .*
是贪婪的,所以它会尽可能地跳过。
使用 strsplit
的解决方法
> tail(strsplit(x, "\D+")[[1]], 1)
[1] "01"
假设我有一个字符串
"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)
解释:
\d+
- 匹配 1 个或多个数字,尽可能多(?![^\r\n\d]*\d)
- 否定前瞻以确保字符串后面没有更多数字
这可行:
(\d+)[^\d]*$
https://regex101.com/r/DHrttA/1
在你的解决方案中,我认为问题是第一个 .*
是贪婪的,所以它会尽可能地跳过。
使用 strsplit
> tail(strsplit(x, "\D+")[[1]], 1)
[1] "01"