为啥这个正则表达式需要一个捕获组来匹配?

Posted

技术标签:

【中文标题】为啥这个正则表达式需要一个捕获组来匹配?【英文标题】:Why is a capture group needed for this regex to match?为什么这个正则表达式需要一个捕获组来匹配? 【发布时间】:2021-12-31 22:16:12 【问题描述】:

理想情况下,我希望不必求助于捕获组,而是断言字符串以某个序列开始/结束,并直接使用正则表达式匹配的值。

输入:

    map_Ks     ./CarbonFiber_T.tga

输入定义:

行首 可能有些空格 字符串map_Ks(这是我要赋值的类字段) 一个或多个空格 a valid file path, 除了 0x00-0x1F, 0x7C (这是我要分配给该字段的值) 可能有些空格 行尾

Attempt 1:它可以工作,但结果在捕获的组中

(?:^\s+map_K.\s+)([^\x00-\x1F\x7C]+)$

  map_Ks     ./CarbonFiber_T.tga
./CarbonFiber_T.tga

Attempt 2:有效,没有分组,但匹配的是整行(理想用法)

(?=^\s+map_K.\s+)[^\x00-\x1F\x7C]+$

  map_Ks     ./CarbonFiber_T.tga

问题:

这有可能吗,还是我对正则表达式引擎的要求太多而应该使用捕获组?

【问题讨论】:

你想看看后面,(?<=^\s+map_K.\s+)(?=\S)[^\x00-\x1F\x7C]+$(见.NET regex demo)。不要使用 regex101 来测试 .NET 正则表达式的有效性。 它几乎可以工作,只是它捕获路径中的前导和尾随空格,我应该修剪你的意思的结果值吗? [start of match] ./CarbonFiber_T.tga [end of match] 您到底想达到什么目标?您是否只需要验证整条生产线是否符合您的要求?那么尝试2有什么问题?您是否需要生产线的任何特定部分进行进一步处理?然后您需要捕获组或后视 @derpirscher 已更新,我想捕获以map_K. 开头的行的文件路径 不,我的意思是尝试#2,因为正如您所说,它有效(即验证行的正确性)但匹配整行。在您明确表示您实际上想要提取路径之前,我写了此评论......如果您只需要提取路径,我会参考@WiktorStribiżew 的答案,后面看,或者您使用尝试#1 和捕获组。 .. 【参考方案1】:

您需要将前瞻替换为后瞻,并要求使用模式的第一个字符是非空白字符。

你可以使用

(?<=^\s+map_K.\s+)(?=\S)[^\x00-\x1F\x7C]*(?<=\S)(?=\s*$)
(?<=^\s+map_K.\s+)[^\x00-\x1F\x7C\s](?:[^\x00-\x1F\x7C]*[^\x00-\x1F\x7C\s])?(?=\s*$)

请参阅regex demo(或this regex demo)。 详情

(?&lt;=^\s+map_K.\s+) - 一个正向的向后查找,它匹配紧接在字符串开头、一个或多个空格、map_K、除 LF 字符之外的任何一个字符、一个或多个空格的位置 (?=\S) - 要求下一个字符为非空白字符的正向前瞻 [^\x00-\x1F\x7C]+ - 一个或多个非 ASCII 控制字符的字符 (?&lt;=\S) - 前一个字符必须是非空白字符 (?=\s*$) - 一个正向前瞻,需要在右侧的字符串末尾有零个或多个空格。

[^\x00-\x1F\x7C\s](?:[^\x00-\x1F\x7C]*[^\x00-\x1F\x7C\s])? 正则表达式部分匹配一个不是空格且不是 ASCII 控制字符的字符,然后是任意零个或多个字符的可选序列,而不是 ASCII 控制字符,然后是一个不是空格的单个字符和不是 ASCII 控制字符。

如果你想调整文件路径正则表达式部分,请参考What characters are forbidden in Windows and Linux directory names?

【讨论】:

这几乎是完美的,只是它捕获了路径中的尾随空格,我尝试将其更改为 (?&lt;=^\s+map_K.\s+)(?=\S)[^\x00-\x1F\x7C]+(?=\s*?)$ 但失败了。 至于有效的补丁字符,你绝对是对的,我应该升级那个表达式! 感谢您的帮助 Wiktor,您又一次成功了!还是需要消化一下才能完全明白。将使用您的有效字符建议对其进行升级,并希望成功! @aybe 我不确定它是用于 Windows 还是 Linux 等。这里是a possible update。

以上是关于为啥这个正则表达式需要一个捕获组来匹配?的主要内容,如果未能解决你的问题,请参考以下文章

为啥正则表达式可选非捕获组不作为可选并且搞砸匹配?

正则表达式:为啥这些行中的文字“鲍勃”不匹配?

为啥这个正则表达式匹配?

为啥这个正则表达式不匹配这个文本?

为啥这个正则表达式不生成匹配?

为啥这个正则表达式模式不匹配? [复制]