如何在`K`重置匹配的情况下使用捕获组?

人气:85 发布:2023-01-03 标签: regex pcre regex-group

问题描述

我找到了this question有关使用K重置匹配的捕获组的信息(即,不确定该名称是否正确),但它没有回答我的问题。

假设我有以下字符串:

ab

以下regexaKb输出如预期的b

但是,使用regex(aKb)添加捕获组(即$1)时,组$1返回ab而不是a

给定以下字符串:

ab
cd

使用regex(aKb)|(cKd)我希望组$1包含b,组$2包含d,但情况并非如此,如下所示:

我尝试了Wiktor Stribiżew的答案,它指向使用branch reset group:

(?|aKb)|(?|cKd)

这会产生:

但是,现在匹配项都是$0组的一部分,而我要求它们分别属于$1组和$2组。你对如何实现这一点有什么想法吗?我正在使用Oniguruma regular expressions和PCRE口味。

根据下面的评论进行更新。

上面的示例旨在易于理解和重现。 @Booboo指出,非捕获组起作用,即:

(?:aK(b))|(?:cK(d))

生成输出:

然而,当应用到另一个示例时,它失败了。因此,为清楚起见,我将这个问题扩展到包括评论中讨论的更复杂的情况。

假设我在markdown文件中有以下文本:

- [x] Example task. | Task ends. [x] Another task.
- [x] ! Example task. | This ends. [x] ! Another task.

This is a sentence. [x] Task is here.
Other text. Another [x] ! Task is here.

|       | Task name     |    Plan     |   Actual    |      File      |
| :---- | :-------------| :---------: | :---------: | :------------: |
| [x]   | Task example. | 08:00-08:45 | 08:00-09:00 |  [[task-one]]  |
| [x] ! | Task example. | 08:00-08:45 | 08:00-09:00 |  [[task-one]]  |

我对具有两个捕获组的单个regex表达式感兴趣,如下所示:

$1(即参见下面的选择):

表外:捕获[x]之后的所有内容(即不跟!),直到|

表内:捕获[x]之后的所有内容(即不是!),不包括|符号

$2(即参见下面的选择):

表外:捕获[x] !之后的所有内容,直到|

表内:捕获[x] !之后的所有内容,不包括|符号

我有以下regex(即see demo here),它们在单独评估时有效,但在捕获组内使用时不起作用:

$1: 表外:[^|s]s*[x]s*K[^!| ]* 表内:(?:G(?!A)||(?<=[x]s)s*|)K[^| ]*(?=|)$2: 表外:[^|s]s*[x]s*!s*K[^| ]* 表内:(?:G(?!A)||(?<=[x]s)s*!s*|)K[^| ]*(?=|)

我遇到的问题是在组合上面的表达式时。

regex

([x] outside|[x] inside)|([x] ! outside|[x] ! inside)

实际regex

([^|s]s*[x]s*K[^!|
]*|(?:G(?!A)||(?<=[x]s)s*|)K[^|
]*(?=|))|([^|s]s*[x]s*!s*K[^|
]*|(?:G(?!A)||(?<=[x]s)s*!s*|)K[^|
]*(?=|))

产生(即,如demo linked above):

表内匹配项的regex基于Wiktor Stribiżew的答案和explained here。

推荐答案

您可以使用

(?|(?:G(?!A)(?<=|)|^|h*[x]h*|)h*K([^|
]+)(?<=S)h*||[x]h*K([^|s!]+(?:h*[^|s]+)*))|(?|(?:G(?!A)||^|h*[x]h*!h*|)h*K([^|
]+)(?<=S)h*|[x]h*!h*K([^|s]+(?:h*[^|s]+)*))

参见regex demo。详细信息:

(?|(?:G(?!A)(?<=|)|^|h*[x]h*|)h*K([^| ]+)(?<=S)h*||[x]h*K([^|s!]+(?:h*[^|s]+)*))-A分支重置组匹配:

(?:G(?!A)(?<=|)|^|h*[x]h*|)-匹配以下任一项的非捕获组 G(?!A)(?<=|)-前一次成功匹配的结束,前面紧跟一个|字符 |-或 ^|h*[x]h*|-行/字符串的开始,|,零个或多个水平空格,[x],零个或多个水平空格,| h*K-匹配后立即从匹配值中丢弃的零个或多个水平空格 ([^| ]+)(?<=S)-组1:除LF和|之外的一个或多个字符,尽可能多,但块应与非空格字符匹配 h*|-零个或多个水平空格和一个|字符

|-或

[x]h*K-[x],零个或多个水平空格,该文本将从匹配值中丢弃 ([^|s!]+(?:h*[^|s]+)*)-组1(注意是分支重置组):!|和空格以外的一个或多个字符,然后零个或多个水平空格,然后是|和空格以外的一个或多个字符

|-或

(?|(?:G(?!A)||^|h*[x]h*!h*|)h*K([^| ]+)(?<=S)h*|[x]h*!h*K([^|s]+(?:h*[^|s]+)*))-分支重置组:

(?:G(?!A)||^|h*[x]h*!h*|)-上一次成功匹配的结束,|字符之后或字符串的开头,|,零个或多个水平空格,[x]!,用零个或多个水平空格括起来,|字符 h*K-从匹配值中丢弃零个或多个水平空格和迄今为止匹配的整个文本 ([^| ]+)(?<=S)-组2:除LF和|以外的任何一个或多个以非空格字符结尾的字符 h*-零个或多个水平空格

|-或

[x]-a[x]字符串 h*!h*K-!包含零个或多个水平空格,到目前为止匹配的整个文本将从匹配值中丢弃 ([^|s]+(?:h*[^|s]+)*)-组2(注意是分支重置组):|和空格以外的一个或多个字符,然后零个或多个水平空格,然后是|和空格以外的一个或多个字符。

14