如何用正则表达式匹配含可选多行内容的文件条目?
正则匹配带多行可选部分的文件条目解决方案
问题分析
你有一个包含特定格式条目的文件,每个条目分为两部分:
- 必填固定部分:格式为
日期时间. 标签. 描述. #问题ID,例如09-05-2023 13:15. Feature. Test ticket. #OW72-59 - 可选部分:多行内容,每行以两个空格开头,例如
New feature description.
现有正则能正确匹配必填部分,但无法捕获这些多行可选内容,且你可以根据需要调整文件格式。
解决方案
第一步:优化文件格式(推荐)
给每个条目之间添加空行分隔,明确区分不同条目,大幅降低正则匹配的复杂度。调整后的文件格式示例:
09-05-2023 13:15. Feature. Test ticket. #OW72-59
New feature description.
Supports multiple user roles.09-06-2023 09:30. BugFix. Login issue. #OW72-60
Fixes incorrect password validation.
第二步:使用优化后的正则表达式
针对调整后的格式,用以下正则可以同时捕获必填部分和所有可选多行内容:
(?s)(?'date'\d{2}-\d{2}-\d{4}\s\d{2}:\d{2})\. (?'tag'\w+)\. (?'desc'.*?)\. #(?'issueId'\w+-\d+)(?:\n (?'optional'.+))*
正则关键说明:
(?s):开启单行模式,让.可以匹配换行符(?'date'\d{2}-\d{2}-\d{4}\s\d{2}:\d{2}):精准匹配DD-MM-YYYY HH:MM格式的日期时间,避免原正则\d*的宽泛匹配(?:\n (?'optional'.+))*:匹配所有以两个空格开头的可选行,*表示允许0次(无可选内容)或多次匹配
若无法调整文件格式的替代方案
如果不能添加空行分隔,可以用以下正则匹配到下一个非空格开头的行(即下一个条目的起始行)为止:
(?s)(?'date'\d{2}-\d{2}-\d{4}\s\d{2}:\d{2})\. (?'tag'\w+)\. (?'desc'.*?)\. #(?'issueId'\w+-\d+)(?:\n .+)*?(?=\n[^ ]|\Z)
正则关键说明:
(?=\n[^ ]|\Z):正向预查,确保只捕获当前条目的可选内容,不会误包含下一个条目的内容
测试验证
用示例文本测试上述正则:
09-05-2023 13:15. Feature. Test ticket. #OW72-59 New feature description. Supports multiple user roles. 09-06-2023 09:30. BugFix. Login issue. #OW72-60 Fixes incorrect password validation. Resolves session timeout bug.
匹配后会准确捕获每个条目的所有字段:
- 第一个条目:
- date:
09-05-2023 13:15 - tag:
Feature - desc:
Test ticket - issueId:
OW72-59 - optional:
New feature description.、Supports multiple user roles.
- date:
- 第二个条目:
- date:
09-06-2023 09:30 - tag:
BugFix - desc:
Login issue - issueId:
OW72-60 - optional:
Fixes incorrect password validation.、Resolves session timeout bug.
- date:
内容的提问来源于stack exchange,提问作者Sergey Alikin
相关产品推荐
相关产品推荐

