[英]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>
, split
和join
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.