首页 > 解决方案 > C# 正则表达式优化

问题描述

我有一个 C# 应用程序,我正在使用 RegEx 运行来自 Unix 响应的期望。我目前有这个。

//will pick up :
//  What is your name?:
//  [root@localhost ~]#
//  [root@localhost ~]$
//  Do you want to continue [y/N]
//  Do you want to continue [Y/n]
const string Command_Prompt_Only = @"[$#]|\[.*@(.*?)\][$%#]";
const string Command_Question_Only = @".*\?:|.*\[y/N\]/g";
const string Command_Prompt_Question = Command_Question_Only + "|" + Command_Prompt_Only;

这很有效,因为我已经使用www.regexpal.com对其进行了测试,但是我认为我需要一些优化,因为有时,当我使用 Command_Prompt_Question 时它似乎会变慢。

var promptRegex = new Regex(Command_Prompt_Question);
var output = _shellStream.Expect(promptRegex, timeOut);

我可能想提一下我正在使用 SSH.NET 与这些 Linux 服务器通信,但我认为这不是 SSH.NET 问题,因为当我使用 Command_Prompt_Only 时它很快。

有人看到我使用的 const 字符串有任何问题吗?有更好的方法吗?

如果您想尝试一下,我的项目是开源的。
https://github.com/gavin1970/Linux-Commander

有问题的代码: https ://github.com/gavin1970/Linux-Commander/blob/master/Linux-Commander/common/Ssh.cs

它叫做 Linux Commander,我正在尝试构建一个支持 Ansible 的虚拟 linux 控制台。

标签: c#regex

解决方案


有人看到我使用的 const 字符串有任何问题吗?

是的,这些模式中有太多的回溯。

如果知道至少有一项,则指定一个*零或多个)会导致解析器查看许多零类型断言。最好选择+(一个或多个)乘数,它可以节省大量时间来研究回溯中的死胡同。


这很有趣\[.*@(.*?)\],为什么不使用集 ( [^ ]) 模式,例如这个变化:

\[[^@]+@[^\]+\]

这表示锚定文字 "[" 并找到 1 个或多个不是文字 "@" ( [^@]+) 的项目,然后找到 1 个或多个不是文字 "]" 的项目[^\]+


推荐阅读