我正在开发一个解析文本文件的项目。该文件从网络设备输出。传入的字符串长度可达数千到数万行。将有可变数量的条目,其中包含以下关键字:
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'和'port-channel'条目在每个条目之后将具有与fcN / N条目相似的状态信息。所有相同类型的条目将被分组 - 不会有fc后面跟着另一个fc的fcip。同样作为一般规则,列出所有fc条目,然后是所有端口通道然后所有fcip但我不想假设。目前我正在寻找约7种不同的RegEx模式。我通过依次检查每一行来做到这一点,但是管理所有这些是很麻烦的。我考虑过在换行符上拆分字符串然后使用某种LINQ选择来获取所有3种类型的条目,但是假设它们总是以相同的顺序分组。我还想到了3个怪物正则表达式,以匹配从一个入口到下一个入口的所有内容,但我的经验是那些难以开始工作且几乎不可读。我想到的另一件事是首先匹配三个关键字--fc或port-channel或fcip,然后有一个if语句匹配那些独特的模式。这仍然匹配所有3种模式的每一行。
要清楚,我有正则表达式模式。我正在寻找一种更有效的方法,而不是测试6 0 8 8场比赛的每一行。
还有其他想法吗?
答案 0 :(得分:0)
我有两个想法:
(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)));
答案 1 :(得分:0)
使用解析器组合器库(例如Sprache)可能会获得更清晰,更简洁的代码。
不是C#程序员,我对这个库并不熟悉(也可能有其他C#),但我使用Scala解析器组合效果很好,并且它们构建并使用常规表达式解析。
是否使代码更高效可能取决于您的代码现在效率低下。
答案 2 :(得分:0)
您是在寻找原始速度还是效率?如果是前者,您可以将文件拆分为多个部分,并让一个线程同时解析每个部分。诀窍将是快速找到要拆分的边界(以便每个部分仅包含整个条目)。如果总行数很大,或者开销将超过并行化增益,您也只想要多线程。