我的正则表达式有什么问题?

时间:2011-10-19 17:27:57

标签: .net regex c++-cli

我正在使用System::Text::RegularExpressions::Regex尝试在日志文件中查找启动消息。我的表达如下:

using namespace System::Text::RegularExpressions;
Regex^ logStartRegex = gcnew Regex( "^=+ .* \\((\\d+)/(\\d+)/(\\d+) @ (\\d+):(\\d+):(\\d+)\\) (.*) =+", static_cast<RegexOptions>(RegexOptions::Compiled | RegexOptions::IgnoreCase) );

...我的测试数据是:

========= Logging started (07/10/2011 @ 15:38:54) v1.000 AA000 =========

...但是当我执行以下操作时,我没有得到匹配:

logStartRegex->Match( "========= Logging started (07/10/2011 @ 15:38:54) v1.000 AA000 =========\n" );

我在regexpal中对其进行了测试,表明它有效(请注意,在C ++版本中,我们必须转义所有'\'字符):^=+ .* \((\d+)/(\d+)/(\d+) @ (\d+):(\d+):(\d+)\) (.*) =+。有什么办法可以看出这究竟是什么?

2 个答案:

答案 0 :(得分:1)

我刚刚尝试了以下程序,复制了您提供的内容:

using namespace System;
using namespace System::Text::RegularExpressions;

int main(array<System::String ^> ^args)
{
   Regex^ logStartRegex = gcnew Regex( "^=+ .* \\((\\d+)/(\\d+)/(\\d+) @ (\\d+):(\\d+):(\\d+)\\) (.*) =+", static_cast<RegexOptions>(RegexOptions::Compiled | RegexOptions::IgnoreCase) );
   Match^ match = logStartRegex->Match( "========= Logging started (07/10/2011 @ 15:38:54) v1.000 AA000 =========\n" );
   Console::WriteLine(match->Success);
   Console::ReadKey();    
   return 0;
}

它向屏幕写出True,表示它找到了匹配项。所以我认为问题必须在你的程序中的其他地方。

答案 1 :(得分:1)

我相信这应该遵循.Net Framework正则表达式的约定,虽然我不太了解C ++但是如果它不是,并且更倾向于Java实现和API,就像[正则表达式] Matcher.matches()方法,它将尝试将正则表达式与整个源匹配(如果它与整个源匹配,但可能只匹配其中的一部分,则尝试将失败)。对Regex.Match()函数的.Net调用将在提供的输入中查找表达式,如果找到

则返回true

这是一个很长的说法:确保您的输入字符串不包含任何尾随空格或其他字符。

还有一点需要注意 - 如果您的输入实际上是多行,特别是其他行包含括号()中的日期和时间 - 您的表达式包括应用于点字符类“.”的贪心量词至少会使它非常缓慢地运行以获得大量输入,如果不是以某种方式将其绊倒并使其失败。

在任何情况下,您都可以通过将.*的实例分别更改为[^(]*[^=]*来提高您的表达效率,如下所示:

"^=+ [^(]* \\((\\d+)/(\\d+)/(\\d+) @ (\\d+):(\\d+):(\\d+)\\) ([^=]*) =+"

你要替换的贪婪量词否则会多次匹配整个字符串,然后多次回溯,最后回到十到二十个字符之后才开始说“哦,好吧,这匹配...下一步是什么?“