我需要在不使用模块的情况下解析XML文件。
在该XML文件中,我需要提取与模式匹配的2个标记(<mi>
... </mi>
)之间的所有内容。
我有这个:
$xmlstring = my xml string
$pattern = "G2_CPU";
my $regex = "<mi>(.*?" . $pattern . ".*?)<\\/mi>";
my ($data) = $xmlstring =~ /$regex/i;
但是当我执行它时,在$data
中,我在第一个<mi>
标记和最后一个</mi>
标记之间得到了所有内容。
我也尝试使用没有变量的正则表达式:/(<mi>.*?G2_CPU.*?<\/mi>)/
,我得到了相同的结果。
我该怎么做?
答案 0 :(得分:3)
假设这仍然是有效的XML,即<
无法在标记打开和标记关闭之间显示, 和 ,那些内容中没有CDATA
标签,你可以使用:
my $re = qr{<mi>([^<]*? \Q$pattern\E [^<]*?)</mi>}ix;
也就是说,不要让任何字符到感兴趣的子字符串,只允许使用非标记的开头字符。
另外,我的第一直觉,如果我以为我会尝试go down the rabbit hole在没有合适的XML解析器的情况下解析XML,那么首先要在<mi>...</mi>
之间提取文本,然后检查它是否存在包含我正在寻找的东西。
答案 1 :(得分:1)
你只需要在模式的开头添加一个贪婪的匹配,这样就可以捕获它的大部分:
my $regex = "(?:.*)<mi>(.*?" . $compteur . ".*?)<\/mi>";
^^^^^^
问题在于,即使使用非贪婪的匹配,Perl仍然存在 试图找到从最左边可能的点开始的匹配 字符串。
档案p.pl
:
$xmlstring = "hello <mi>first mi</mi> and this is another <mi>second mi</mi> end." ;
$compteur="second";
my $regex = "(?:.*)<mi>(.*?" . $compteur . ".*?)<\/mi>";
my ($data) = $xmlstring =~ /$regex/i;
print "$data\n";
执行:
$ perl p.pl
second mi