【问题标题】:Incrementing a value in an XML file using Perl regex使用 Perl 正则表达式增加 XML 文件中的值
【发布时间】:2014-05-15 05:03:41
【问题描述】:

我正在使用 Oxygen 为 ehumanities 项目以 XML 格式编码文本。

这个文件预编码了几个标签,大部分都放错了,所以我不得不整理很多。大部分已经完成,但仍然存在一个主要问题。

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

这些分页符有 300 多个。

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

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

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

并且可以将其替换为:

<pb n="$1"/>

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

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

【问题讨论】:

  • RegEx 不能做这种逻辑,但大多数语言允许你做某种replace callback,你可以在其中引用匹配并执行++ 操作。
  • 氧气如何影响这个问题?

标签: xml regex perl


【解决方案1】:

使用 XML 时,使用 XML 解析器几乎总是有利的。但是,鉴于所提供的信息,我认为这个“可能”是只使用正则表达式的合理实例。

使用 perl 单行和正则表达式

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

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

【讨论】:

  • 我觉得你的答案和我的很相配
  • 在这种情况下允许使用正则表达式的建议让我非常困扰。考虑到提供的信息,它可能会起作用,但我们必须担心的始终是未说明的信息。我还打算提供一个解析器解决方案,但你已经做到了,所以是的,它们确实配对得很好:)
【解决方案2】:

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

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

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

请注意,我已经抓取了您问题的一部分并将其包含在根元素中,以用作示例输入数据。如果您可以在问题中提供自己的代表性数据,那总是最好的。

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

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>

【讨论】:

  • 感谢您的回答。不幸的是,我不知道如何使用 xml 解析器。所以我要先学习一下,试试你的建议。
  • 有没有办法在 XSLT 中做到这一点?因为我只是不知道如何使用 perl 或 xml 解析器。
  • @Basti:有什么问题?我的解决方案按照您的要求使用 XML::LibXML 解析 XML 数据
  • 抱歉,我对 XML 很陌生,只是不知道 XML 解析器是什么或如何使用它。我什至设法下载了 LibXML,但我不知道如何使用它。
  • @Basti:我不明白你有什么困惑。我的解决方案向您展示如何使用XML::LibXML。你不需要知道更多,尽管理想情况下你会理解它是如何工作的。您需要做的唯一更改是打开您要用作输入的真实文件,并在 load_xml 方法调用中将其替换为 DATA
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-20
  • 2022-01-11
  • 2020-08-16
相关资源
最近更新 更多