如何用正则表达式提取字符串中指定格式的子串(含跨多行场景)
解决方案:精准捕获特定格式的跨多行文本块
一、简化“CNTY开头//结尾”子串的提取
你之前的正则思路没问题,我可以给你一个更简洁高效的写法:
// 直接拼接所有符合规则的子串,替代原来的Aggregate写法 var result = string.Concat(Regex.Matches(text, @"CNTY.*?//"));
.*?采用非贪婪匹配,能避免单个匹配项意外包含多个//结尾的内容,确保匹配精度string.Concat比Aggregate写法更简洁,性能也更优
二、实现“WEATHLOC开头 + 跨多行内容 + RMKS行//结尾”的捕获
针对你提到的复杂跨场景需求,我们可以结合正则的多行模式和单行模式来实现精准匹配:
正则表达式与代码示例
// 定义匹配规则 var pattern = @"^WEATHLOC.*?^RMKS.*//$"; // 启用单行模式(让.匹配换行符)+ 多行模式(让^/$匹配每行首尾) var matches = Regex.Matches(text, pattern, RegexOptions.Singleline | RegexOptions.Multiline); // 拼接所有捕获到的目标文本块 var result = string.Concat(matches.Cast<Match>().Select(m => m.Value));
模式细节拆解
^WEATHLOC:在多行模式下,匹配行首的WEATHLOC,确保只捕获以它为起始的文本块.*?:非贪婪匹配任意字符(包括换行符,因为启用了Singleline模式),直到找到后续的结尾标记,避免过度匹配多个块^RMKS.*//$:在多行模式下,匹配行首的RMKS,然后匹配该行直到行尾的//,严格锁定结尾格式RegexOptions.Singleline:让.能匹配换行符,支持捕获跨多行的中间内容RegexOptions.Multiline:让^和$不再局限于整个字符串的首尾,而是匹配每一行的开头和结尾
测试你的示例文本
对于你提供的示例内容:
WEATHLOC/ICAO:KCOS// OBSTIME/052005Z// WIND/360/10// VSBY/10/SM// CLDLYR/-/LYR:BKN// TEMP/MAXTEMP:15/MINTEMP:18// ALTSTG/HG:29.92// RMKS/SAMPLE//
这个正则会完整捕获从WEATHLOC到RMKS/SAMPLE//的全部内容,完全符合你的需求。
额外说明
- 如果文本中有多个符合条件的
WEATHLOC-RMKS//块,Regex.Matches会捕获所有匹配项,再通过string.Concat拼接起来 - 正则会自动保留原始文本的换行格式,不会修改内容结构
内容的提问来源于stack exchange,提问作者Buck




