正则表达式 - 捕获排除周围部分匹配内容的重复组
Regex - Capturing repeating groups excluding surrounding partially matching content
郑重声明,我使用的是 R,但我的查询与平台无关(就目前而言),因此我将使用 regex101 进行演示。我试图捕捉重复的组,这些组可能会或可能不会被其他文本包围。所以理想的行为显示在这个演示中:
demo1
正则表达式:(\d{2})(AB)
文本:blahblah11AB12AB13ABblah
所以它很好地捕获了我想要的所有组:
匹配 1
Full match 8-12 `11AB`
Group 1. 8-10 `11`
Group 2. 10-12 `AB`
匹配 2
Full match 12-16 `12AB`
Group 1. 12-14 `12`
Group 2. 14-16 `AB`
匹配 3
Full match 16-20 `13AB`
Group 1. 16-18 `13`
Group 2. 18-20 `AB`
但是,如果我包含另一段匹配的文本,它也会捕获该文本(我想这很公平)
正文:blahblah11AB12AB13ABblah22AB
returns 相同,但多了一个组:
匹配 4
Full match 24-28 `22AB`
Group 1. 24-26 `22`
Group 2. 26-28 `AB`
我想做的是捕获第一组但忽略所有其他文本,即使有后续匹配项也是如此。本质上,我只想从这个文本中获得三个匹配项:blahblah11AB12AB13ABblah22AB
我试过很多东西,比如这个:
(((\d{2})(AB))+)(.*)
但后来我得到了以下内容,它丢失了最后一组捕获的所有内容:
匹配 1
Full match 8-28 `11AB12AB13ABblah22AB`
Group 1. 8-20 `11AB12AB13AB`
Group 2. 16-20 `13AB`
Group 3. 16-18 `13`
Group 4. 18-20 `AB`
Group 5. 20-28 `blah22AB`
我需要保留重复组的东西。我很难过!
在 R 中,输出应如下所示:
[[1]]
[,1] [,2] [,3]
[1,] "11AB" "11" "AB"
[2,] "12AB" "12" "AB"
[3,] "13AB" "13" "AB"
提前致谢...
如果我没理解错的话,问题出在括号的位置上。
pattern <- "(\d{2}AB)"
s <- "blahblah11AB12AB13ABbla"
m <- gregexpr(pattern, s)
regmatches(s, m)
#[[1]]
#[1] "11AB" "12AB" "13AB"
s2 <- "blahblah11AB12AB13ABblah22AB"
s3 <- "11AB12AB13ABblah22AB"
S <- c(s, s2, s3)
m <- gregexpr(pattern, S)
regmatches(S, m)
#[[1]]
#[1] "11AB" "12AB" "13AB"
#
#[[2]]
#[1] "11AB" "12AB" "13AB" "22AB"
#
#[[3]]
#[1] "11AB" "12AB" "13AB" "22AB"
请注意,很多时候这只是一个代码行中的 运行。为了更清楚,我将其保留为这样。
编辑。
也许以下内容满足了 OP 的要求。
我敢打赌有更好的解决方案,在我看来,两个正则表达式是一种矫枉过正。
pattern <- "((\d{2}AB)+)([^[:digit:]AB]+(\d{2}AB))"
pattern2 <- "(\d{2}AB)"
m <- gregexpr(pattern2, gsub(pattern, "\1", S))
regmatches(S, m)
#[[1]]
#[1] "11AB" "12AB" "13AB"
#
#[[2]]
#[1] "11AB" "12AB" "13AB"
#
#[[3]]
#[1] "11AB" "12AB" "13AB"
您可以使用量词 {3}
来获得前 3 个组:(((\d{2})(AB)){3})
。参见 demo
一个想法会在 use \G
for chaining matches to ^
start and reset by \K
之后。
(?:^.*?\K|\G)(\d{2})(AB)
^.*?\K
将在第一次匹配之前延迟匹配任意数量的任意字符
|\G
或在上一场比赛结束时继续,可以是:开始、第一、上一场
这将匹配第一个匹配链并且是一个 pcre 模式 (perl=TRUE
)。
如果在第一个匹配之前只能有非数字,use ^\D*\K
instead of ^.*?\K
.
郑重声明,我使用的是 R,但我的查询与平台无关(就目前而言),因此我将使用 regex101 进行演示。我试图捕捉重复的组,这些组可能会或可能不会被其他文本包围。所以理想的行为显示在这个演示中: demo1
正则表达式:(\d{2})(AB)
文本:blahblah11AB12AB13ABblah
所以它很好地捕获了我想要的所有组:
匹配 1
Full match 8-12 `11AB`
Group 1. 8-10 `11`
Group 2. 10-12 `AB`
匹配 2
Full match 12-16 `12AB`
Group 1. 12-14 `12`
Group 2. 14-16 `AB`
匹配 3
Full match 16-20 `13AB`
Group 1. 16-18 `13`
Group 2. 18-20 `AB`
但是,如果我包含另一段匹配的文本,它也会捕获该文本(我想这很公平)
正文:blahblah11AB12AB13ABblah22AB
returns 相同,但多了一个组:
匹配 4
Full match 24-28 `22AB`
Group 1. 24-26 `22`
Group 2. 26-28 `AB`
我想做的是捕获第一组但忽略所有其他文本,即使有后续匹配项也是如此。本质上,我只想从这个文本中获得三个匹配项:blahblah11AB12AB13ABblah22AB
我试过很多东西,比如这个:
(((\d{2})(AB))+)(.*)
但后来我得到了以下内容,它丢失了最后一组捕获的所有内容:
匹配 1
Full match 8-28 `11AB12AB13ABblah22AB`
Group 1. 8-20 `11AB12AB13AB`
Group 2. 16-20 `13AB`
Group 3. 16-18 `13`
Group 4. 18-20 `AB`
Group 5. 20-28 `blah22AB`
我需要保留重复组的东西。我很难过!
在 R 中,输出应如下所示:
[[1]]
[,1] [,2] [,3]
[1,] "11AB" "11" "AB"
[2,] "12AB" "12" "AB"
[3,] "13AB" "13" "AB"
提前致谢...
如果我没理解错的话,问题出在括号的位置上。
pattern <- "(\d{2}AB)"
s <- "blahblah11AB12AB13ABbla"
m <- gregexpr(pattern, s)
regmatches(s, m)
#[[1]]
#[1] "11AB" "12AB" "13AB"
s2 <- "blahblah11AB12AB13ABblah22AB"
s3 <- "11AB12AB13ABblah22AB"
S <- c(s, s2, s3)
m <- gregexpr(pattern, S)
regmatches(S, m)
#[[1]]
#[1] "11AB" "12AB" "13AB"
#
#[[2]]
#[1] "11AB" "12AB" "13AB" "22AB"
#
#[[3]]
#[1] "11AB" "12AB" "13AB" "22AB"
请注意,很多时候这只是一个代码行中的 运行。为了更清楚,我将其保留为这样。
编辑。
也许以下内容满足了 OP 的要求。
我敢打赌有更好的解决方案,在我看来,两个正则表达式是一种矫枉过正。
pattern <- "((\d{2}AB)+)([^[:digit:]AB]+(\d{2}AB))"
pattern2 <- "(\d{2}AB)"
m <- gregexpr(pattern2, gsub(pattern, "\1", S))
regmatches(S, m)
#[[1]]
#[1] "11AB" "12AB" "13AB"
#
#[[2]]
#[1] "11AB" "12AB" "13AB"
#
#[[3]]
#[1] "11AB" "12AB" "13AB"
您可以使用量词 {3}
来获得前 3 个组:(((\d{2})(AB)){3})
。参见 demo
一个想法会在 use \G
for chaining matches to ^
start and reset by \K
之后。
(?:^.*?\K|\G)(\d{2})(AB)
^.*?\K
将在第一次匹配之前延迟匹配任意数量的任意字符|\G
或在上一场比赛结束时继续,可以是:开始、第一、上一场
这将匹配第一个匹配链并且是一个 pcre 模式 (perl=TRUE
)。
如果在第一个匹配之前只能有非数字,use ^\D*\K
instead of ^.*?\K
.