C#如何编写匹配DeviceNr开头、ready结尾且含指定内容的多行正则
问题原因
你原来的正则出现跨块匹配的核心问题是:非贪婪匹配(?:.*?\n)*?仅会尽可能少匹配字符,但不会限制匹配范围,会从第一个DeviceNr开头的块直接向后匹配,直到找到符合要求的Model = XYZ,最终把前后两个Device块都包含进匹配结果。
解决方案
通过限制匹配范围确保匹配过程中不会跨过下一个DeviceNr开头的块,同时配合正确的正则选项即可实现需求。
最终正则表达式
^\s*DeviceNr : ([0-9]+)(?:(?!^\s*DeviceNr).)*?DeviceClass = ABC(?:(?!^\s*DeviceNr).)*?Model = XYZ(?:(?!^\s*DeviceNr).)*?^\s*ready$
调用说明
C#中调用时需要传入两个正则选项:
RegexOptions.Multiline:让^和$匹配每一行的首尾,而非整个文本的首尾RegexOptions.Singleline:让.可以匹配换行符,简化多行匹配逻辑
示例代码
using System.Text.RegularExpressions; // 你的待匹配文本 string input = @" DeviceNr : 30 DeviceClass = ABC UnitNr = 1 Reference = 29 PhysState = ENABLED LogState = OPERATIVE DevicePlan = 702 Manufacturer = CDE Model = EFG ready DeviceNr : 31 DeviceClass = ABC UnitNr = 9 Reference = 33 PhysState = ENABLED LogState = OPERATIVE Manufacturer = DDD Model = XYZ Description = something here ready"; // 匹配规则 string pattern = @"^\s*DeviceNr : ([0-9]+)(?:(?!^\s*DeviceNr).)*?DeviceClass = ABC(?:(?!^\s*DeviceNr).)*?Model = XYZ(?:(?!^\s*DeviceNr).)*?^\s*ready$"; var matches = Regex.Matches(input, pattern, RegexOptions.Multiline | RegexOptions.Singleline); // 输出结果 foreach (Match match in matches) { Console.WriteLine($"匹配到的设备块:\n{match.Value}"); Console.WriteLine($"设备编号:{match.Groups[1].Value}\n"); }
核心逻辑说明
正则中的(?:(?!^\s*DeviceNr).)*?是匹配范围控制的核心:它会匹配任意字符,但永远不会匹配到以DeviceNr开头的行,确保所有匹配内容都在同一个设备块内部,不会出现跨块匹配的问题。
内容的提问来源于stack exchange,提问作者PolarnyMis
相关产品推荐
相关产品推荐

