使用正则表达式搜索可能包含竖线字符的多个字符串 [duplicate]

Searching using RegEx for multiple strings that might include pipe character [duplicate]

提问人:NoBullMan 提问时间:11/1/2023 最后编辑:NoBullMan 更新时间:11/2/2023 访问量:102

问:

我使用了一个代码,该代码在一组文件中搜索多个字符串,该代码工作正常,直到我在其中一个搜索字符串中包含竖线字符。它吼道。

这是我一直在使用的,但不确定如何修改它以接受竖线字符作为搜索的一部分。

这里“fi”是我正在搜索的当前文件的 FileInfo 变量,searchStr 是一个包含我正在搜索的字符串的数组。

foreach (var line in Extensions.WriteSafeReadAllLines(fi.FullName))    // This method fixes the issue of reading lines when file is open.
{
    // Escape "|" character in search strings
    SearchStr = SearchStr.Select(l => l.Replace("|", @"\|")).ToArray();

    string pattern = string.Join("|", SearchStr);  // <-- what if one of the search strings has '|'
    MatchCollection matches = Regex.Matches(line, pattern, RegexOptions.Multiline);

    foreach (Match match in matches)
    {
        string theEntireLine = match.Groups[0].Value;
        // do whatever with the line that contains any of the search strings
    }
}

正在搜索的文件中的示例行:

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

SearchStr 数组现在包含:

"00:34:31:162\\|2023-10-31"
"128101dLZ240126628"

它匹配每一行包含“2023-10-31”的行,即使这样,它也不会返回整行,而是返回“2023-10-31”

如果我使用 RegEx.Escape,正如 Nick 所建议的那样,“模式”将如下所示:

\\|00:34:31:162\\|2023-10-31|128101dLZ240126628
C# 正则表达式

评论

1赞 B.O.B. 11/1/2023
正则表达式中的反斜杠是转义字符串。在做字符串之前。Join,您可以浏览 SearchStr 中的每个条目,并将“|”替换为“\|”。
0赞 NoBullMan 11/1/2023
问题是我正在搜索多个字符串,其中“|”在正则表达式中使用。如果我使用 RegEx.Escape(“|”),作为 RegEx 一部分的管道字符不会也被转义吗?我已经用@B.O.B.建议更新了这个问题,但仍然不起作用。
0赞 NoBullMan 11/1/2023
不知道为什么会有“接近”的投票,这不是任何问题的重复。在决定是时候发帖和咨询专家之前,我确实进行了广泛的搜索。
0赞 NoBullMan 11/1/2023
基本问题是:如果我正在搜索多个字符串,并且其中一个或多个字符串恰好包含“|”,那么如果正则表达式本身使用“|”作为分隔符,我该如何继续?如果我搜索 1234|5678,而不是返回带有 1234|5678 的行,它会返回匹配 1234 或 5678 的行。尝试将“|”替换为“\|”或使用 RegEx.Escape(“|”) + searchStr 不起作用。
0赞 B.O.B. 11/2/2023
您可以在自己的 SearchStr 数组中看到,您以某种方式对其进行了双重转义。您也可以在正则表达式中转义转义字符。因此,如果您的输入是 ,那么用于转义它的输出应该是 。"00:34:31:162|2023-10-31""00:34:31:162\|2023-10-31"
1赞 NoBullMan 11/4/2023
@Nick 谢谢你的信息。我将使用该站点进行将来的测试。我认为重复意味着已经有一个类似的答案问题,由其他人提出,这表明我没有做功课,而不是我的示例代码和某人的响应/答案会表示重复。无论如何,感谢大家的投入和B.O.B的回答。

答:

-1赞 B.O.B. 11/2/2023 #1

如果我正确理解了您的问题,首先,将模式创建移到循环之外,否则您将在循环的每次迭代中对模式进行多转义。

其次,每当一行与任何搜索字符串匹配时,您都希望整行。为此,您只需要在 for 循环中引用变量:line

SearchStr = SearchStr.Select(l => Regex.Escape(l)).ToArray();
string pattern = string.Join("|", SearchStr);

foreach (var line in Extensions.WriteSafeReadAllLines(fi.FullName))
{
    if (Regex.IsMatch(line, pattern))
    {
        Console.WriteLine($"This line matched one or more of the search patterns: {line}");
    }
}

评论

0赞 B.O.B. 11/2/2023
PS,这是我使用您的示例行 + 搜索过滤器返回的 2 行:和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:59:268|2023-10-31 00:34:59:268,[1.23.4:12870],ABC,X,102,128101dLZ240126628 RLCAYT2R0W8 20231028060553 },