R正则表达式捕获组?

3

我有很多这样的字符串:

2019/01/01/07/556662_cba3a4fc-cb8f-4150-859f-5f21a38373d0

我想提取最后一个斜杠后面以及以"_"结尾的子字符串:
Original Answer 翻译成 "最初的回答"。
556662

我发现如何提取:/01/01/07/556662,使用以下正则表达式:(\/)(.*?)(?=\_),请指导如何捕获正确的组。"最初的回答"
3个回答

5

您可以使用

x <- "2019/01/01/07/556662_cba3a4fc-cb8f-4150-859f-5f21a38373d0"
regmatches(x, regexpr(".*/\\K[^_]+", x, perl=TRUE))
## [1] "556662"

请看正则表达式R演示
在这里,该正则表达式匹配并输出第一个与以下条件匹配的子字符串:
  • .*/ - 尽可能多地匹配直到最后一个/之前的任意0个或多个字符。
  • \K - 省略此部分的匹配结果。
  • [^_]+ - 将一个或多个不为_的字符放入匹配值中。
或者可以使用sub方法来解决:
sub(".*/([^_]+).*", "\\1", x)

以下是您需要翻译的内容:

请参见正则表达式演示

这里与前一个示例类似,但除了_之外的1个或多个字符被捕获到第1组(\1在替换模式中),并且结尾的.*确保整个输入被匹配(并消耗,准备被替换)。

非基本R解决方案的替代方法

如果您可以承受或更喜欢使用stringi,则可以使用以下方法

library(stringi)
stri_match_last_regex("2019/01/01/07/556662_cba3a4fc-cb8f-4150-859f-5f21a38373d0", ".*/([^_]+)")[,2]
## [1] "556662"

这将匹配字符串直到最后一个/,并将其捕获到组1中(您可以使用[,2]在第二列中访问该组),该组中包含一个或多个字符,但不包括_
或者,
stri_extract_last_regex("2019/01/01/07/556662_cba3a4fc-cb8f-4150-859f-5f21a38373d0", "(?<=/)[^_/]+")
## => [1] "556662"

这将提取一个由除了_/之外的1个或多个字符组成的字符串在/之后的最后一个匹配项。


1
太棒了!简单明了,专业解决方案直指问题!感谢Wiktor!!! @wiktor-stribizew - SteveS
@SteveS 我也添加了非基本R正则表达式的解决方案。 - Wiktor Stribiżew

4

您可以使用捕获组:

/([^_/]+)_[^/\s]*

解释

  • / 意为字面匹配斜线
  • ([^_/]+) 捕获一个组,其中的内容不应是下划线或正斜线
  • _[^/\s]* 匹配 _,然后匹配 0 次或多次非斜线或空格字符

正则表达式演示 | R 演示

使用 str_match 可以获取第二列来获取捕获组的一种方法:

library(stringr)
str = c("2019/01/01/07/556662_cba3a4fc-cb8f-4150-859f-5f21a38373d0")
str_match(str, "/([^_/]+)_[^/\\s]*")[,2]

# [1] "556662"

这不是我需要的,我想提取最后一个 / 和 _ 之间的任何内容。 - SteveS
@SteveS 那是在第一个捕获组中。我已经更新了我的答案。 - The fourth bird
但我不需要最后一个 / 和 _ 之间的子字符串。 - SteveS
我该如何提取我所需的部分。 - SteveS

0

我根据Wiktor Stribiżew的代码更改了正则表达式规则。

x <- "2019/01/01/07/556662_cba3a4fc-cb8f-4150-859f-5f21a38373d0"
regmatches(x, regexpr(".*/([0-9]+)", x, perl=TRUE))
sub(".*/([0-9]+).*", "\\1", x)

输出

[1] "2019/01/01/07/556662"

[1] "556662"

R demo


请注意,OP在帖子中没有提到在最后一个“/”和下一个“_”之间应该只有数字。 - Wiktor Stribiżew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接