正则表达式搜索含竖线的多字符串时出现异常求解决
问题:搜索含竖线(|)的字符串时正则匹配异常
原代码如下:
foreach (var line in Extensions.WriteSafeReadAllLines(fi.FullName)) // 解决文件被占用时的读行问题 { // 转义搜索字符串中的"|"字符 SearchStr = SearchStr.Select(l => l.Replace("|", @"\|")).ToArray(); string pattern = string.Join("|", SearchStr); // <-- 如果搜索字符串本身包含'|'就会出问题 MatchCollection matches = Regex.Matches(line, pattern, RegexOptions.Multiline); foreach (Match match in matches) { string theEntireLine = match.Groups[0].Value; // 处理包含任意搜索字符串的行 } }
待搜索文件的示例行:
2023-10-31 00:34:31:162|2023-10-31 00:34:31:162,[1.23.4:12870],ABC,XX,102,128001dLV816409130 RLCAYV0B 1M0 20231025152123 }, 2023-10-31 00:34:58:940|2023-10-31 00:34:58:940,[1.23.4:12870],XX,ABC,60,d128101LZ240126628 }, 2023-10-31 00:34:59:268|2023-10-31 00:34:59:268,[1.23.4:12870],ABC,X,102,128101dLZ240126628 RLCAYT2R0W8 20231028060553 },
搜索字符串:
00:34:31:162|2023-10-31 128101dLZ240126628
当前代码的问题:
- 手动替换
|为\|后,拼接的正则模式会把00:34:31:162\|2023-10-31拆成00:34:31:162和2023-10-31两个匹配项,导致所有含2023-10-31的行都被匹配,且仅返回子串而非整行。 - 使用
Regex.Escape也会因为转义后拼接的逻辑错误,出现类似问题。
解决方案
核心修正点:
- 对每个搜索字符串单独做完整正则转义,而非仅转义
|; - 明确需求:若只需判断行是否包含目标字符串,直接用整行处理,无需从匹配子串提取。
修改后的代码(仅需判断行是否匹配)
// 提前对所有搜索字符串做正则转义,避免循环内重复处理 var escapedSearchStrings = SearchStr.Select(Regex.Escape).ToArray(); // 用括号包裹每个转义后的字符串,确保竖线作为分隔符的逻辑正确 string pattern = $"({string.Join("|", escapedSearchStrings)})"; foreach (var line in Extensions.WriteSafeReadAllLines(fi.FullName)) { // 只要行中存在任意匹配项,直接处理整行 if (Regex.IsMatch(line, pattern, RegexOptions.Multiline)) { string theEntireLine = line; // 这里编写整行的处理逻辑 } }
代码说明
Regex.Escape:自动转义所有正则特殊字符(包括|、.、()等),确保每个搜索字符串被当作普通文本匹配。- 括号包裹模式:保证每个搜索项是独立的匹配单元,避免转义后的字符干扰分隔符
|的逻辑。 Regex.IsMatch:比Matches更高效,直接判断行是否符合条件,无需遍历匹配集合。
若需同时获取匹配子串
如果需要保留匹配子串的获取逻辑,可修改为:
var escapedSearchStrings = SearchStr.Select(Regex.Escape).ToArray(); string pattern = string.Join("|", escapedSearchStrings); foreach (var line in Extensions.WriteSafeReadAllLines(fi.FullName)) { MatchCollection matches = Regex.Matches(line, pattern, RegexOptions.Multiline); if (matches.Count > 0) { string theEntireLine = line; // 处理整行逻辑 // 遍历所有匹配的子串 foreach (Match match in matches) { string matchedSubstring = match.Value; // 处理子串逻辑 } } }
内容的提问来源于stack exchange,提问作者NoBullMan
相关产品推荐
相关产品推荐

