使用Perl正则表达式增加XML文件中的值

时间:2014-05-14 19:59:44

标签: xml regex perl

我正在用XML编写一个XML文本,用于使用Oxygen的非常规项目。

该文件预先编码了几个标签,其中大多数都放错了,所以我不得不整理它。大部分都已完成,但仍存在一个主要问题。

分页符<pb n="number"/>编号错误。严格来说,它们的价值实在太少,这意味着<pb n="3"/>应该是<pb n="4"/>

这些分页符有300多个。

有没有办法通过Perl替换来递增每个值?

我设法用这个正则表达式模式找到每个值

<pb n="(\d+)"/>

并可以替换为:

<pb n="$1"/>

但是我如何对每个值进行+1操作?

我不熟悉XPath和XSLT,但我愿意学习它。

2 个答案:

答案 0 :(得分:1)

使用XML时,使用XML Parser几乎总是有利的。但是,鉴于所提供的信息,我认为这可能&#34;是一个只使用正则表达式是合理的实例。

使用perl单行和正则表达式

perl -i -pe 's{<pb n="\K(\d+)(?="/>)}{$1++}eg' file.xml

对于am XML Parser,我建议使用XML::TwigXML::LibXML

答案 1 :(得分:1)

虽然您可能找到了一个与您想要更改的所有元素相匹配的正则表达式模式,但它远非可靠。 XML文档可能与您的示例有很大差异,但仍然包含等效数据,但您的代码不会提取它。

因此,最好采用适当的XML解析器。

我在这里使用了XML::LibXMLXML::Twig也是一个不错的选择。

请注意,我已抓住您问题的一部分并将其括在根元素中,以用作示例输入数据。如果您能在问题中提供自己的代表性数据,那么这是最好的。

XPath表达式查找名为n的所有属性,这些属性属于名为pb的元素。在循环中检查所有这些属性,看它们是否只包含一个或多个数字,在这种情况下,值会递增

use strict;
use warnings;

use XML::LibXML;

my $doc = XML::LibXML->load_xml(IO => *DATA);

for my $pb_n ( $doc->findnodes('//pb/@n') ) {
  my $val = $pb_n->getValue;
  if ( $val =~ /\A(\d+)\z/a ) {
    $pb_n->setValue($1 + 1);
  }
}

print $doc->toString;

__DATA__
<root>
  The page breaks <pb n="number"/> are wrong numbered. Strictly speaking 
  their value is exactly one too little, which means <pb n="3"/> is 
  supposed to be <pb n="4"/>.
</root>

<强>输出

<?xml version="1.0"?>
<root>
  The page breaks <pb n="number"/> are wrong numbered. Strictly speaking 
  their value is exactly one too little, which means <pb n="4"/> is 
  supposed to be <pb n="5"/>.
</root>