为啥这个正则表达式需要一个捕获组来匹配?
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)。 详情:
(?<=^\s+map_K.\s+)
- 一个正向的向后查找,它匹配紧接在字符串开头、一个或多个空格、map_K
、除 LF 字符之外的任何一个字符、一个或多个空格的位置
(?=\S)
- 要求下一个字符为非空白字符的正向前瞻
[^\x00-\x1F\x7C]+
- 一个或多个非 ASCII 控制字符的字符
(?<=\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?
【讨论】:
这几乎是完美的,只是它捕获了路径中的尾随空格,我尝试将其更改为(?<=^\s+map_K.\s+)(?=\S)[^\x00-\x1F\x7C]+(?=\s*?)$
但失败了。
至于有效的补丁字符,你绝对是对的,我应该升级那个表达式!
感谢您的帮助 Wiktor,您又一次成功了!还是需要消化一下才能完全明白。将使用您的有效字符建议对其进行升级,并希望成功!
@aybe 我不确定它是用于 Windows 还是 Linux 等。这里是a possible update。以上是关于为啥这个正则表达式需要一个捕获组来匹配?的主要内容,如果未能解决你的问题,请参考以下文章