簡體   English   中英

在Perl中,如何匹配兩個連續的回車?

[英]In Perl, how to match two consecutive Carriage Returns?

嗨StackOverflow好友,

我在Windows平台上 ; 我有一個數據文件但發生了錯誤(我不知道為什么)“回車+新線”的所有組合變成了“回車+回車+新線”, (190128編輯:)例如:

以純文本格式查看文件時,它是:

純文本文本文件(帶有不可打印的東西)

以十六進制模式查看同一文件時,它是:

十六進制模式下的文本文件,可以看到雙“0D”

出於實際目的,我需要刪除雙“0D”中的額外“0D”,如“ .... 30 30 0D 0D 0A 30 30 .... ”,並將其更改為“ .... 30 30 0D 0A 30 30 ....

190129編輯:此外,為了確保我的問題可以重現,我將我的數據文件上傳到GitHub的URL(應該在使用之前下載並解壓縮;在二進制\\十六進制編輯器中,你可以在第一行中輸入0D 0D 0A ): https ://github.com/katyusza/hello_world/blob/master/ram_init.zip

我使用以下Perl腳本來刪除額外的回車,但令我驚訝的是我的正則表達式不起作用! 我的整個代碼是( 190129編輯 :過去整個Perl腳本):

use warnings            ;
use strict              ;
use File::Basename      ;

#-----------------------------------------------------------
# command line handling, file open \ create
#-----------------------------------------------------------

# Capture input input filename from command line:
my $input_fn = $ARGV[0] or
die "Should provide input file name at command line!\n";

# Parse input file name, and generate output file name:
my ($iname, $ipath, $isuffix) = fileparse($input_fn, qr/\.[^.]*/);
my $output_fn = $iname."_pruneNonPrintable".$isuffix;

# Open input file:
open (my $FIN, "<", $input_fn) or die "Open file error $!\n";

# Create output file:
open (my $FO, ">", $output_fn) or die "Create file error $!\n";


#-----------------------------------------------------------
# Read input file, search & replace, write to output
#-----------------------------------------------------------

# Read all lines in one go:
$/ = undef;

# Read entire file into variable:
my $prune_txt = <$FIN> ;

# Do match & replace:
 $prune_txt =~ s/\x0D\x0D/\x0D/g;          # do NOT work.
# $prune_txt =~ s/\x0d\x0d/\x30/g;          # do NOT work.
# $prune_txt =~ s/\x30\x0d/\x0d/g;          # can work.
# $prune_txt =~ s/\x0d\x0d\x0a/\x0d\x0a/gs; # do NOT work.

# Print end time of processing:
print $FO $prune_txt  ;

# Close files:
close($FIN)     ;
close($FO)      ;

我盡我所能來匹配兩個連續的回車,但失敗了。 任何人都可以指出我的錯誤,或告訴我正確的方法去? 提前致謝!

在Windows上,文件句柄默認為它們提供:crlf層。

  • 該層在讀取時將CR LF轉換為LF。
  • 該層在寫入時將LF轉換為CR LF。

解決方案1:補償:crlf層。

如果您希望最終得到系統相應的行結尾,則可以使用此解決方案。

# ... read ...      # CR CR LF ⇒ CR LF
s/\r+\n/\n/g;       # CR LF    ⇒ LF
# ... write ...     # LF       ⇒ CR LF

解決方案2:刪除:crlf圖層。

如果您想無條件地使用CR LF,則可以使用此解決方案。

使用<:raw>:raw而不是<>作為模式。

# ... read ...      # CR CR LF ⇒ CR CR LF
s/\r*\n/\r\n/g;     # CR CR LF ⇒ CR LF
# ... write ...     # CR LF    ⇒ CR LF

你的第一個正則表達似乎對我來說很好,這意味着在其他一些代碼中可能存在問題。 請提供最小, 完整和可驗證的示例 ,這意味着包括樣本輸入數據等。

$ perl -wMstrict -e 'print "Foo\r\r\nBar\r\r\n"' >test.txt
$ hexdump -C test.txt 
00000000  46 6f 6f 0d 0d 0a 42 61  72 0d 0d 0a              |Foo...Bar...|
0000000c
$ cat test.pl 
#!/usr/bin/env perl
use warnings;
use strict;
use Data::Dump;

my $filename = 'test.txt';
open my $fh, '<:raw:encoding(ASCII)', $filename or die "$filename: $!";
my $prune_txt = do { local $/; <$fh> }; # slurp file
close $fh;

dd $prune_txt;
$prune_txt =~ s/\x0D\x0D/\x0D/g;
dd $prune_txt;

$ perl test.pl
"Foo\r\r\nBar\r\r\n"
"Foo\r\nBar\r\n"

順便說一句,對我來說,哪個編碼文件正在使用並不是很明顯? 在上面的示例中,您可能需要適當地調整:encoding(...)圖層。

暫無
暫無

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

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