为何C#中正则匹配每行最后8位字符时仅返回最后一行结果?
问题产生原因
该问题由两类因素共同导致:
- 换行符格式差异:C# 中
TextBox控件的文本换行默认使用 CRLF 格式(即行尾为\r\n),而RegexOptions.Multiline模式下,正则的$锚点仅匹配\n之前的位置,不会跳过行尾的\r字符。你使用的正则中末尾匹配字符组[\d\w]+无法匹配\r,因此前5行均匹配失败,仅无尾随行结束符的最后一行能正常匹配。正则测试平台默认使用 LF 换行(行尾仅为\n),因此测试时不会出现该问题。 - 字符串转义问题:你代码中的正则字符串未添加
@逐字字符串前缀,C#会将字符串内的\d、\w中的反斜杠识别为转义符,导致实际传入正则引擎的规则和预期不一致,也会引发匹配异常。
解决方案
方案1:修改正则适配规则
只需调整正则适配CRLF换行,同时添加@前缀避免转义问题即可:
// 调整正则增加\r?适配行尾回车符,加@避免转义问题 var reg = new Regex(@"^(([\d\w]+ ){1,})?([\d\w]+)\r?$", RegexOptions.Multiline); if (reg.IsMatch(textBox1.Text)) { var instructions = reg.Matches(textBox1.Text).Cast<Match>().Select(x => x.Groups[3].Value).ToArray(); foreach (var instruction in instructions) { MessageBox.Show(instruction); } }
也可以使用更精简的正则直接匹配每行末尾的8位十六进制字符块,实现相同需求:
var reg = new Regex(@"([0-9A-Fa-f]{8})\r?$", RegexOptions.Multiline); // 直接取分组1的值即可 var instructions = reg.Matches(textBox1.Text).Cast<Match>().Select(x => x.Groups[1].Value).ToArray();
方案2:直接拆分文本处理(更稳定)
如果不需要强依赖正则,直接按行拆分、按空格分割取最后一段的实现方式更不易受换行格式影响,性能也更高:
var instructions = textBox1.Text.Split(new[] {'\r', '\n'}, StringSplitOptions.RemoveEmptyEntries) .Select(line => line.Split(' ', StringSplitOptions.RemoveEmptyEntries).Last()) .ToArray(); foreach (var instruction in instructions) { MessageBox.Show(instruction); }
内容的提问来源于stack exchange,提问作者ThePerplexedOne
相关产品推荐
相关产品推荐

