gpt4 book ai didi

c# - RegularExpressions.Regex.IsMatch 挂起

转载 作者:行者123 更新时间:2023-11-30 14:57:28 25 4
gpt4 key购买 nike

这是我的代码的摘录:

string[] myStr =
{
" Line1: active 56:09 - tst0063, tst0063",
"Contacts accosiated with line 1 - tst0063, tst0063",
"Line 1: 00:00:32 Wrap: 00:00:20 - tst0063, tst0063",
"Line 1: 00:00:17 Active: 00:00:15 - tst0064, tst0064"
};

string sPattern = @"^Line(\s*\S*)*tst0063$";
RegexOptions options = RegexOptions.IgnoreCase;

foreach (string s in myStr)
{
System.Console.Write(s);

if (System.Text.RegularExpressions.Regex.IsMatch(s, sPattern, options))
{
System.Console.WriteLine(" - valid");
}
else
{
System.Console.WriteLine(" - invalid");
}
System.Console.ReadLine();
}

RegularExpressions.Regex.IsMatch 在处理最后一行时挂起。我做了一些实验,但仍然不明白为什么当行尾没有匹配时它会挂起。请帮忙!

最佳答案

问题不是为什么第四个测试挂起,而是为什么前三个没有挂起。第一个字符串以空格开头,第二个字符串以 Contacts 开头,两者都不匹配正则表达式 ^Line,因此前两次匹配尝试立即失败。第三个字符串匹配正则表达式;虽然它比它应该花费的时间长得多(出于我将要解释的原因),它似乎仍然是瞬间的。

第四次匹配失败,因为字符串与正则表达式的结尾部分不匹配:tst0063$。当失败时,正则表达式引擎将备份到正则表达式的可变部分 (\s*\S*)*,并开始尝试所有不同的方式将其放入字符串中。与第三个字符串不同,这次它必须尝试零个或多个空白字符 (\s*) 后跟零个或多个非空白字符 (\S*), 零次或多次, 在它可以放弃之前。可能性不是无限的,但也可能是无限的。

您可能想到了 [\s\S]*,这是一个众所周知的习惯用法,用于匹配任何字符包括换行符。它在 JavaScript 中使用,它没有办法使点 (.) 匹配行分隔符。大多数其他风格允许您指定一个匹配模式来改变点的行为;有些人称之为 DOTALL 模式,但 .NET 使用更常见的 Singleline

string sPattern = @"^Line.*tst0063$";
RegexOptions options = RegexOptions.IgnoreCase | RegexOptions.Singleline;

您还可以使用内联修饰符:

string sPattern = @"(?is)^Line.*tst0063$";

更新:是的,作为对您评论的回应,正则表达式引擎无法判断任何匹配项必须tst0063< 结尾,这似乎确实很奇怪。但它并不总是那么容易分辨。寻找这样的捷径需要付出多少努力?在所有 匹配(成功和失败)变得太慢之前,您可以在正常匹配算法上使用多少条捷径?

.NET 拥有目前最好的正则表达式实现之一:快速、强大,并且具有一些真正令人惊叹的特性。但是您必须考虑要告诉它做什么。例如,如果您知道必须至少有一个,请使用 +,而不是 *。如果您遵循该规则,就不会遇到这个问题。这个正则表达式:

@"^Line(\s+\S+)*tst0063$"

...工作得很好。 (\s+\S+)* 是一种非常合理的匹配零个或多个单词的方法,其中单词被定义为一个或多个非空白字符,由一个或多个空白字符与其他单词分隔开。 (这就是你想要做的吗?)

关于c# - RegularExpressions.Regex.IsMatch 挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20778554/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com