簡體   English   中英

關於 Perl 正則表達式腳本的建議

[英]Advice on Perl regular expression script

我正在嘗試編寫一個腳本,該腳本將從文本文件中讀取,並將與正則表達式不匹配的行輸出到另一個文件。

我有一個包含兩列的文件 - 第一列是庫杜威數字,第二列是條形碼。 杜威數應該類似於 150 ADD 或 150.40 ADD。 我正在尋找缺少 3 個字符作者首字母的行。 我的示例文件如下所示:

100.20 SAD 350694345
250 ADD 369803434
300 360349320
300.1534234 ZOO 353000303
210 3633400340

我編寫了一個腳本來輸出杜威數字后沒有作者姓名首字母的所有行。 正則表達式在可選點之前查找三位數字,然后是零個或多個可選數字,然后是一個空格,然后是作者姓名首字母的三個字母。

$filename = 'call.txt';
$output = 'result.txt';
open(FILE, $filename) or die 'Could not open $filename';
foreach $line (<FILE>) {
    if ($line !~ /^\d{3}\.*\d* [a-zA-Z]{3}/) {

        open (CALL, '>', $output) or die $!;
        print CALL $line;
    }
}

當我運行腳本時,它只輸出第五行:

210 3633400340

為什么它不也選擇第 3 行,因為它與正則表達式不匹配? 輸出應該是沒有作者姓名首字母的所有杜威數。 所以所需的輸出是:

300 360349320
210 3633400340

問題:

  • 您應該始終使用use strict; use warnings qw( all ); use strict; use warnings qw( all ); . (因為它應該總是被使用,所以我們不費心在我們的代碼片段中展示它。)這可以免費檢測到許多問題。
  • 您不必要地使用全局變量。 use strict;將幫助你,除了文件句柄。)
  • 通過在循環中重復創建文件,除了最后一行輸出之外,您正在破壞所有內容。 (這就是你問的問題。)
  • 您的模式錯誤地將超過三個字符的序列視為三個字符的序列。
  • 通過在列表上下文中使用<> ,您將整個文件加載到內存中,而從文件中逐行讀取它本來是很容易的。
  • 您的錯誤消息不是很有用。

固定的:

#!/usr/bin/perl

use strict;
use warnings qw( all );

my $in_qfn  = 'call.txt';
my $out_qfn = 'result.txt';

open(my $fh_in, '<', $in_qfn)
   or die("Can't open \"$in_qfn\": $!\n");
open(my $fh_out, '>', $out_qfn)
   or die("Can't create \"$out_qfn\": $!\n");

while (<$fh_in>) {
   print $out_fh $_ if !/^\S+\s+\S{3}\s/;
}

如果您不對文件名進行硬編碼,該程序會更有用。

#!/usr/bin/perl

use strict;
use warnings qw( all );

while (<>) {
   print if !/^\S+\s+\S{3}\s/;
}

用法:

script call.txt >result.txt

或者

script <call.txt >result.txt

每次找到匹配項時,您都會使用截斷 (">") 打開文件。 在 for 循環之前移動 open(CALL, ...) 。

暫無
暫無

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

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