我正在尝试设计Perl正则表达式来解析IBM的runmqsc实用程序的命令输出。
输出的每一行都包含一个或多个属性/值对,格式为“ATTRIBUTE(VALUE)"。属性的值可以为空,也可以包含括号本身。通常,给定行上最多出现两个属性/值对,因此正则表达式是在此假设下编写的。
Perl RE的输入示例:
CHANNEL(TO.IPTWX01) CHLTYPE(CLUSRCVR)
DISCINT(6000) SHORTRTY(10)
TRPTYPE(TCP) DESCR( )
LONGTMR(1200) SCYEXIT( )
CONNAME(NODE(1414)) MREXIT( )
MREXIT( ) CONNAME2(SOME(1416))
TPNAME( ) BATCHSZ(50)
MCANAME( ) MODENAME( )
ALTTIME(00.41.56) SSLPEER()
CONTRIVED() ATTR (00-41-56)
CONTRIVED() DOCTORED()
MSGEXIT( )
我有以下Perl代码来捕获每个属性/值对。
Perl代码
my $resplit = qr/\s+([^\s]+(?:\([^)]*\))?)\s?/;
while ( <IN2> )
{ s/[\s\r\n]+$//;
if ( m/^\s(?:$resplit)(?:$resplit)?$/ )
{ my ($one,$two) = ($1,$2);
print "one: $one, two: $two\n";
}
}
以下是将上述代码应用于样本输入时的输出:
one: CHANNEL(TO.IPTWX01), two: CHLTYPE(CLUSRCVR)
one: DISCINT(6000), two: SHORTRTY(10)
one: TRPTYPE(TCP), two: DESCR( )
one: LONGTMR(1200), two: SCYEXIT( )
one: CONNAME(NODE(1414)), two: MREXIT( )
one: MREXIT( ), two: CONNAME2(SOME(1416))
one: TPNAME( ), two: BATCHSZ(50)
one: MCANAME( ), two: MODENAME( )
one: ALTTIME(00.41.56), two: SSLPEER()
one: CONTRIVED(), two: ATTR(00-41-56)
one: CONTRIVED(), two: DOCTORED()
one: MSGEXIT(, two: )
除了上面输出中的最后一行之外,这一步都很好用。我真的很难弄清楚如何修改上面的表达式$resplit来捕获最后一种情况。
有没有人能就如何使这一工作或另一种方法提供任何想法/建议?
4条答案
按热度按时间jum4pzuy1#
Text::Balanced模块就是为处理这类问题而设计的,这种方法也可以处理任意数量的列。
li9yvcax2#
我想尝试使用
Regexp::Grammars
。这就是:
0qx6xfy63#
这适用于嵌套的括号,例如。
(?)2)部分是递归的,*+表示“不回溯”-仅适用于Perl 5.10或更高版本;我从Can I use Perl regular expressions to match balanced text得到这个?
sqserrrh4#