连续多次替换的替代方案?

时间:2016-02-10 22:14:19

标签: regex perl

我的大多数Perl脚本都处理将丑陋格式转换为普通TXT内容的问题。到目前为止,我已经连续几十次和几十次替换完成了这项工作。在Perl中有更优雅的方法吗?例如,包含所有s ///对的哈希,甚至是包含替换的外部文件?

我只是想知道其他人如何处理这种格式化脚本,或者只是有一个小说的值// s /表达式是正常的方法。在某一点上很难管理。

谢谢!

4 个答案:

答案 0 :(得分:2)

有时最有效的方法是将旧数据格式解析为内存结构,然后输出新格式。

根据结构,这可以逐行完成。但是,如果你必须完成有效的整个文件,只要它们不是太大了。

例如,这就是你进行图像文件转换的方法:将GIF读入位图,然后生成JPEG输出。你不会使用正则表达式,即使你可以,它也会非常低效。

答案 1 :(得分:1)

我有一个实用的方法,我一直用它:

curl -s 'http://ichart.finance.yahoo.com/table.csv?s=IDJG.AS&a=10&b=8&c=2015&g=d&ignore=.csv' | sed -e 's/^/yahoo,IDJG,xams,/' > yahoo_IDJG.csv;

我使用列表而不是sub subst($@) { my($x, @map) = @_; @map % 2 == 0 or die 'subst requires an odd number of params'; while (@map) { my $from = shift(@map); my $to = shift(@map); $x =~ s/$from/$to/g; } return $x; } 的哈希值,因此我可以控制订单。像这样使用它:

map

即使使用单一模式,如果您不能替换某些内容,也会更简单。即它比这更清洁:

my $new_x = subst($x,
    pattern1 => replacement1,
    pattern2 => replacement2);

答案 2 :(得分:0)

Zan Lynx给出了很好的建议,但是要回答关于哈希驱动的替换的问题,您可以使用以下内容:

my %replacements = (
   foo => 'bar',
   bar => 'baz',
   baz => 'foo',
   # ...
);

my $pat = join '|', map quotemeta, keys %replacements;

s/($pat)/$replacements{$1}/g;

这解决了两个问题:

  • 它只扫描输入一次,而不是每个模式扫描一次。
  • 它消除了意外匹配早期替换的替换的风险。事实上,我使用的例子无法通过三次替换完成。

答案 3 :(得分:-2)

这是一个尴尬的问题,因为替换的顺序会影响结果

如果您的更改非常广泛,那么我更倾向于将一系列s///语句添加到哈希中的任何内容中,这会在每次运行程序时将替换顺序改为不同的顺序

我仍然会担心“数十和数十”(200加?)的替换的准确性,但至少结果会受到控制