簡體   English   中英

Perl 中替換正則表達式的意外結果

[英]Unexpected result of substitution regex in Perl

我有一個腳本和一個文件。

[evelden@vatasu4435 perl]$ cat file
06:35:42,734
foo 06:35:42 bar

[evelden@vatasu4435 perl]$ cat script
#!/usr/bin/perl
while(<>){
    if(s/(\d\d:\d\d).*/\1/){
        print;
    }
}

所以在正則表達式的后面它說。*,但不是在前面。

做,

[evelden@vatasu4435 perl]$ ./script file
06:35
foo 06:35

顯然。* 最后需要盡可能多的,這沒關系。

但我不明白答案中“foo”的來源。 這是我的問題。

如果我將正則表達式更改為: s/.*(\d\d:\d\d).*/\1/ ,前面還有 dus.*,那么答案就是我所期望的:

[evelden@vatasu4435 perl]$ script file
35:42
35:42

現在他在前面很貪婪,但這沒關系。

當前行的內容放在$_中。 s///對該$_進行操作,將完整的模式替換為$1 (或\1 ,如您所說)的內容。 這是模式中第一個捕獲組的內容。 但是您的模式沒有錨定,因此它將開始匹配字符串中的某個位置,並從那里替換。 它正在做你告訴它的事情。

如果您想擺脫前面的所有內容,那么您的第二種模式是正確的。 如果您只想更改以圖案開頭的線條,請在前面使用^錨。

只有與正則表達式匹配的行部分被s///替換。 由於正則表達式未錨定在左側,因此它匹配以時間開頭的行部分,並替換該部分。 匹配前的部分保持不變,所以foo保留在行中。

OP 的原始正則表達式並未具體說明從何處開始或結束捕獲。

s/(\d\d:\d\d).*/\1/ - 在字符串中查找\d{2}:\d{2}及其后的任何內容。 用捕獲的兩個數字\d{2}:\d{2}替換找到的模式( \d{2}:\d{2}.* - 后面有任何內容的數字)。 模式中沒有與\d{2}:\d{2}之前的內容相關的任何內容,並且沒有對此部分應用替換 - 沒有觸及foo

也許OP打算編寫以下代碼

use strict;
use warnings;

s/.*?(\d{2}:\d{2}):.*/$1/ && print for <>;

解決問題的兩個簡單方法

use strict;
use warnings;
use feature 'say';

while(<DATA>) {
    /(\d{2}:\d{2}):/;
    say $1;
}

__DATA__
06:35:42,734
foo 06:35:42 bar

或其他變體

use strict;
use warnings;
use feature 'say';

while(<DATA>) {
    /\b(\d{2}:\d{2})/;
    say $1;
}

__DATA__
06:35:42,734
foo 06:35:42 bar

或者可能如下

use strict;
use warnings;
use feature 'say';

my $data = do { local $/; <DATA> };
my @time = $data =~ /\b(\d{2}:\d{2})/g;

say for @time;

__DATA__
06:35:42,734
foo 06:35:42 bar

Output

06:35
06:35

暫無
暫無

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

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