我想捕获整行,并且可以选择使用正则表达式模式 H-\d{4}
捕获 ID。 ,例如H-1234
.
这是两个示例行,一个有 ID,另一个没有 ID:
Sample line with H-5722 id
Sample line without id
在第一个 ALL 中应捕获整行,ID H-5722。在第二个中 ALL 应捕获整行,ID 应为空。
此正则表达式适用于第一行,捕获 ALL 和 ID:
^(?<ALL>.*?(?<ID>H-\d{4})\b.*)$
但它与预期的第二行不匹配,因为它没有 ID。
因此,我尝试使用 ?
的非捕获组使 ID 捕获成为可选零或一修饰符(?:(?<ID>H-\d{4}))?
,或者修改 ID 组,以便它可以捕获表达式或空字符串 (?<ID>H-\d{4}|)
:
^(?<ALL>.*?(?:(?<ID>H-\d{4})\b)?.*)$
^(?<ALL>.*?(?<ID>H-\d{4}|)\b.*)$
通过这些修改,ALL 捕获两个示例中的整行。但它不会捕获 ID。
我怎样才能实现这个目标?
我正在使用 .NET 正则表达式实现,但我认为它与其他实现非常相似。
最佳答案
使用交替:
^(?<ALL>(?!.*H-\d{4}\b).*|.*?(?:(?<ID>H-\d{4})\b).*)$
参见https://regex101.com/r/dZx3b1/1/
或者使用 unrolled tempered greedy token (用于性能)
^(?<ALL>[^H\n]*(?:H(?!-\d{4}\b)[^H\n]*)*(?<ID>H-\d{4}\b)?.*)$
参见https://regex101.com/r/9ILEhw/1/
基本上强制使用 ID 组(如果可以找到的话)。
您的方法失败,因为 .*?
始终与初始空字符串匹配,可选的 ID 模式被跳过,并且 .*
与实际字符串匹配。
关于.net - 仅当组存在时才匹配组内的组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48302693/