1

目前,我正在使用以下正则表达式从 Outlook HTML 邮件项目中删除第一个对话项目:

.*?>(([^:]+?):<.*?\2):

为了删除第一个对话项,我只需将组 1 的第一次出现替换为组 2 的值。在 .NET 中看起来有点像这样:

private static readonly Regex LAST_CONVERSATION_REPLACE_PATTERN = new Regex(@".*?>(([^:]+?):<.*?\2):", RegexOptions.Compiled);
// ...
MatchCollection matches = LAST_CONVERSATION_REPLACE_PATTERN.Matches(htmlMessageBody);
if (matches.Count > 0)
{
    Match match = matches[0];
    if (match.Groups.Count > 2)
    {
        return htmlMessageBody.ReplaceFirst(match.Groups[1].ToString(), match.Groups[2].ToString());
    }
}

ReplaceFirst是我自己的字符串扩展方法。不过,这次的表现有点让人失望。虽然 Regex Coach 可以在一微秒内将其应用于大型邮件项目,但在 Outlook 加载项中最多需要 10 秒。

如果我用这个明确的替代方案替换模式,性能会显着提高:

.*?>(From:<.*?From):

使用该正则表达式,只需不到一秒钟的时间就可以得到我想要的。但是,这将是特定于语言的,因此我更喜欢以前的变体。有什么方法可以加快 .NET 的速度吗?或者是否有第三方正则表达式库可以在这个库上表现更好?

感谢您的任何建议和最好的问候

帕斯卡

4

2 回答 2

1

我真的不能说缓慢的原因可能是什么(如果您发布了一些 Outlook 性能不佳的示例文本,我可以)

但是我确实有一些优化正则表达式的想法,尽管如果它们引起了显着的改进,我会感到惊讶。但谁知道 - 让我们试一试。

首先,你不需要让 plus 变得懒惰。相反,您可能希望使其具有所有格或使用原子组。此外,单词边界可能有助于为您的第二场比赛选择合适的起点:

.*?>(((?>[^:]+)):<.*?\b\2):
于 2012-07-15T16:47:05.393 回答
0

我确定这是.*?导致您的问题的原因,两者都是。例如,第一个强制正则表达式停止并尝试在文档开头的每个位置进行匹配。幸运的是,无论如何你都不需要那个部分。但是你真的需要尽可能的更具体,而不是.*?一直依赖。

尝试这个:

private static readonly Regex LAST_CONVERSATION_REPLACE_PATTERN 
    = new Regex(@"^(?>(\w+:).*)(?>\s+(?!^\1).*)+", RegexOptions.Multiline);

我认为可以安全地假设每个标题名称都位于其自己行的开头;毕竟这是电子邮件。它也使工作变得容易得多。事实上,如果你不能假设,你可能会被搞砸。

^(?>(\w+:).*)在一行的开头匹配一个看起来像标题名称的东西,并.*消耗该行的其余部分。将它放在一个原子组中可以确保,如果行首的匹配尝试在正则表达式的后面部分失败,它不会费心回来尝试其他方式来匹配该行。

(?>\s+(?!^\1).*)使用行分隔符和下一行,但仅在前瞻验证它不以目标标题名称开头之后。

于 2012-07-16T17:19:59.157 回答