我正在使用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+)\) (.*) =+
。有什么办法可以看出这究竟是什么?
答案 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调用将在提供的输入中查找表达式,如果找到
这是一个很长的说法:确保您的输入字符串不包含任何尾随空格或其他字符。
还有一点需要注意 - 如果您的输入实际上是多行,特别是其他行包含括号()
中的日期和时间 - 您的表达式包括应用于点字符类“.
”的贪心量词至少会使它非常缓慢地运行以获得大量输入,如果不是以某种方式将其绊倒并使其失败。
在任何情况下,您都可以通过将.*
的实例分别更改为[^(]*
和[^=]*
来提高您的表达效率,如下所示:
"^=+ [^(]* \\((\\d+)/(\\d+)/(\\d+) @ (\\d+):(\\d+):(\\d+)\\) ([^=]*) =+"
你要替换的贪婪量词否则会多次匹配整个字符串,然后多次回溯,最后回到十到二十个字符之后才开始说“哦,好吧,这匹配...下一步是什么?“