簡體   English   中英

Perl正則表達式查找並替換

[英]Perl regex find and replace

我是perl的新手,我試圖找出一個發現並替換。 我有一個很大的csv文件(實際上是用分號隔開)。 文件中的某些數字(整數和小數)在數字之后帶有負號。 我需要將負號移到數字之前。

例如:變更

ABC;10.00-;XYZ

ABC;-10.00;XYZ

我不確定如何在perl中執行此操作。 有人可以幫忙嗎?

問候阿南德

除非我非常確定自己的數據和正則表達式,否則我不會涉足帶有正則表達式的大型csv文件。 在我看來,使用CSV模塊是最安全的方法。

該腳本將輸入文件作為參數,並以.new擴展名寫入更正后的文件。

如果發現輸出文件中發生意外更改,則可以嘗試取消注釋keep_meta_info行。

use strict;
use warnings;
use autodie;
use Text::CSV;

my $out_ext = ".new";
my $csv = Text::CSV->new( { 
        sep_char => ";",
        #   keep_meta_info => 1,
        binary => 1,
        eol => $/,
    } ) or die "" . Text::CSV->error_diag();

for my $arg (@ARGV) {
    open my $input, '<', $arg;
    open my $output, '>', $arg . $out_ext;
    while (my $row = $csv->getline($input)) {
        for (@$row) {
            s/([0-9\.]+)\-$/-$1/;
        }
        $csv->print($output, $row);
    }
}

我假設您不必擔心分隔文件中的引用或轉義。 我將從標准輸入/輸出中讀取,如果需要,請更改為適當的文件

while( my $line = <STDIN> )
{
    chop( $line );
    my @rec = split( ';', $line );
    map( s/^(\d*\.?\d+)\-$/-$1/, @rec );
    print join(';',@rec) . "\n";
}

如果您確實需要擔心轉義和引用,請使用Text :: CSV_XS而不是<STDIN>splitjoin oprerations

通常,replace命令為s/old/new/flags

s/(           # start a capture group
    \d+       # first part of the number
    (\.\d+)?  # possibly a decimal dot and the fractional part
  )-          # end capture group, match the minus sign
 /-$1/gx      # move minus to the front

g標志的意思是“全局”(替換所有出現的情況), x是“擴展易讀性”(允許模式中的空格和注釋)。 您必須對數據上的表達式進行測試,以查看可能遺漏了哪些極端情況,通常需要進行幾次迭代才能找到正確的情況。 樣品:

$ echo "10.5-;10-;0-;a-" | perl -pe 's/(\d+(\.\d+)?)-/-$1/g'
-10.5;-10;-0;a-

另請參見perldoc perlop (搜索“替換”以跳至右側部分)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM