C# 解析字符串-有没有比检查每一行更有效的方法?

C# 解析字符串-有没有比检查每一行更有效的方法?,c#,parsing,C#,Parsing,我正在做一个项目来解析文本文件。该文件是从网络设备输出的。传入字符串的长度从几千到上万行不等。将有不同数量的条目包含以下关键字: fcN/N is up Hardware is Fibre Channel, SFP is short wave laser w/o OFC (SN) Port WWN is 20:52:00:0d:ec:ef:b0:40 Admin port mode is F, trunk mode is on snmp link state trap

我正在做一个项目来解析文本文件。该文件是从网络设备输出的。传入字符串的长度从几千到上万行不等。将有不同数量的条目包含以下关键字:

fcN/N is up
   Hardware is Fibre Channel, SFP is short wave laser w/o OFC (SN)
   Port WWN is 20:52:00:0d:ec:ef:b0:40
    Admin port mode is F, trunk mode is on
    snmp link state traps are enabled
    Port vsan is 10

fcipN is up
.....

port-channel-N is trunking
...... 
N是一个数字。始终存在“fcN/N”条目,可能存在也可能不存在其他两个条目。“fcip”和“端口通道”条目的状态信息与fcN/N条目相似。相同类型的所有条目都将分组-不会有一个fc后跟一个fcip后跟另一个fc。同样作为一般规则,列出所有fc条目,然后列出所有端口通道,然后列出所有fcip,但我不想假设。目前,我有大约7个不同的正则表达式模式,我正在寻找。我通过依次检查每一行来做到这一点,但是管理所有这些都很麻烦。我考虑过在换行符上拆分字符串,然后使用某种LINQ select来获得3种类型的条目中的每一种,但前提是它们总是按相同的顺序分组。我还想用3个怪物正则表达式来匹配从一个条目到下一个条目的所有内容,但我的经验是,这些正则表达式很难使用,而且几乎不可读。我想到的另一件事是首先匹配三个关键字-fc或port channel或fcip,然后使用if语句匹配这些关键字特有的模式。这仍然是匹配所有3个模式的每一行

说得清楚一点,我已经让正则表达式模式工作了。我正在寻找一种更有效的方法来做这件事,而不是测试每行6或8个匹配

还有其他想法吗

我有两个想法:

1使用if语句首先找到要应用的正确正则表达式的最后一种方法是非常有效的。我推荐它

2您可以这样编写正则表达式:

var pattern1 = @"abc";
var pattern2 = @"def";
var unionPattern = "((" + pattern1 + ")|(" + pattern2 + "))";
var chunks = Regex.Split(str, "((fc\d)|(fcip\d)|(port-channel-\d)));
这使它更具可读性

如果不想找到跨行的匹配项,则应首先将文件拆分为多行。这将提高效率,因为正则表达式的输入更小,回溯更少

如果您的匹配跨越多行,但总是在新行之后开始,您可以先将字符串拆分为块,如下所示:

var pattern1 = @"abc";
var pattern2 = @"def";
var unionPattern = "((" + pattern1 + ")|(" + pattern2 + "))";
var chunks = Regex.Split(str, "((fc\d)|(fcip\d)|(port-channel-\d)));

通过使用解析器组合器库,您可能会获得更清晰、更简洁的代码,例如

作为一名C程序员,我对这个库不太熟悉,也可能有其他C库,但我已经使用Scala解析器组合器取得了很好的效果,它们构建并使用正则表达式解析


它是否能提高代码的效率可能取决于您的代码现在的效率有多低

您是在寻找原始速度还是效率?如果是前者,则可以将文件拆分为多个部分,并让一个线程同时解析每个部分。诀窍是找到一个要拆分的边界,以便每个部分只包含整个条目。如果总行数很大,或者开销将超过并行化带来的收益,您也只希望使用多线程。

您现在是否遇到性能问题?正则表达式被编译了吗?没有。我只是在寻找一种比暴力更优雅的方法。也许没有比这更优雅的方式了,我对此很冷静我不知道你可以编译正则表达式,不知道那是什么意思。对不起,我不清楚。输入字符串已包含行。也就是说,我声明了一个StringReader,并让它读取每一行。我将一个字符串设置为该ReadLine,然后在该字符串中搜索所有匹配项。我想我要做的是一种类似于我在主文件中使用的方法。我将搜索关键字。当我找到它时,我会读到下一个关键字并处理我刚得到的块。这样我就不会检查每一行的每一个图案。我从3个主要匹配开始,然后根据我的发现使用其他匹配。我在寻找效率和/或比我现有的更优雅的东西。没有速度问题。整个文件平均为30MB。我搜索了它的几个部分,整个过程在几秒钟内就完成了。我要做的是在文件中搜索一个命令,开始将每一行读入一个字符串,直到我点击下一个命令。然后我将该字符串提供给解析器,解析器解析文件的特定部分。我要问的这一部分恰好有很多模式需要寻找。我想知道是否有更快的方法。