簡體   English   中英

Perl的。 同時匹配和替換

[英]Perl. Simultaneous match and substitution

我試圖找到特定的模式並在其中進行替換。 並將結果分配給另一個變量。

例如:我有一個帶有文本的變量$ text,我試圖在其中查找諸如“ Date:\\ s + \\ d {4}。\\ d \\ d。\\ d \\ d”之類的模式,用點號代替破折號,然后將結果分配給$ result。

此版本適用:

($result) = $text =~ /Date:\s+(\d{4}\.\d\d\.\d\d)/igs;
 $result =~ s/\./-/g;

但是我試圖通過一項手術做到這一點。 就像是:

($result) = $text =~ s/Date:\s+(\d{4})\.(\d\d)\.(\d\d)/$1-$2-$3/igs;

但這給了我結果“ 1”。 因此,問題是:是否可以在一個操作中執行此操作? 還是最好的選擇是這樣做並最小化代碼?

my $result;
$text =~ s/Date:\s+(\d{4})\.(\d\d)\.(\d\d)/ $result= "$1-$2-$3" /ei;

如果移動括號,以便首先將$text分配給$result ,則可以將替換應用於$result而不是$text ,這樣就可以去除所有不需要的多余文本,並使用原始文本建設有破折號日期的想法-而不是點:

(my $result = $text) =~ s/.*Date:\s+(\d{4})\.(\d\d)\.(\d\d).*/$1-$2-$3/igs;

請注意,在字符串的開頭和結尾使用.* ,這將占用所有文本,因此剩下的唯一內容就是日期。 這行代碼實際上是兩個操作合而為一,如下所示:

my $result = $text;
$result =~ s/..../;

另一個版本是使用后腳本for循環,它將利用$_別名為list參數這一事實:

tr/./-/ for ((my $result) = $text =~ /Date:\s+([\d.]+)/);

這會將日期分配給$result ,然后將$result傳遞給for的參數列表,對其應用音譯。 它會影響實變量$result因為$_在循環中具有別名。

另外請注意,我認為這確實是一個學術問題。 我不建議在生產代碼中使用它,並且您的原始版本要好得多且可讀性強。 盡管我將使用音譯而不是替換:

$result =~ tr/./-/;

請嘗試一下($ result = $ text)=〜s / Date:\\ s +(\\ d {4})。(\\ d \\ d)。(\\ d \\ d)/ $ 1- $ 2- $ 3 / igs

您不應該太熱衷於在單個語句中編寫多個操作:它只會破壞代碼的可讀性。 但是我建議你寫這樣的東西。

在原始模式匹配項上使用/s修飾符沒有意義,因為它僅影響. 元字符,並且您的模式中沒有這些字符。 另外,使用/g沒有意義,因為您只對單個匹配感興趣。

不要試圖將兩個語句合並為一行,因為if語句修飾符也將應用於my聲明,這會產生非常奇怪的效果。

use strict;
use warnings;
use 5.010;

my $text = 'Date: 1994.04.04';

my $result;
$result = $1 =~ tr/./-/r if $text =~ /Date:\s+(\d{4}\.\d\d\.\d\d)/i;

say $text;
say $result;

產量

Date: 1994.04.04
1994-04-04

暫無
暫無

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

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