因爲/g
是「全球性」,並會匹配其多次重複:
#!/usr/bin/env perl
use strict;
use warnings;
#turn on debugging
use re 'debug';
my $path = '/path/to/dir/';
$path =~ s/\/?$/\/new/g;
print $path;
第一替補,正則表達式引擎「左」標誌「行結束」後,並不需要匹配可選/
。所以再次匹配。
例如爲:
Compiling REx "/?$"
Final program:
1: CURLY {0,1} (5)
3: EXACT </> (0)
5: SEOL (6)
6: END (0)
floating ""$ at 0..1 (checking floating) minlen 0
Matching REx "/?$" against "/path/to/dir/"
Intuit: trying to determine minimum start position...
doing 'check' fbm scan, [0..13] gave 13
Found floating substr ""$ at offset 13 (rx_origin now 12)...
(multiline anchor test skipped)
try at offset...
Intuit: Successfully guessed: match at offset 12
12 <path/to/dir> </> | 1:CURLY {0,1}(5)
EXACT </> can match 1 times out of 1...
13 <path/to/dir/> <> | 5: SEOL(6)
13 <path/to/dir/> <> | 6: END(0)
Match successful!
Matching REx "/?$" against ""
Intuit: trying to determine minimum start position...
doing 'check' fbm scan, [13..13] gave 13
Found floating substr ""$ at offset 13 (rx_origin now 13)...
(multiline anchor test skipped)
Intuit: Successfully guessed: match at offset 13
13 <path/to/dir/> <> | 1:CURLY {0,1}(5)
EXACT </> can match 0 times out of 1...
13 <path/to/dir/> <> | 5: SEOL(6)
13 <path/to/dir/> <> | 6: END(0)
Match successful!
Matching REx "/?$" against ""
Intuit: trying to determine minimum start position...
doing 'check' fbm scan, [13..13] gave 13
Found floating substr ""$ at offset 13 (rx_origin now 13)...
(multiline anchor test skipped)
Intuit: Successfully guessed: match at offset 13
13 <path/to/dir/> <> | 1:CURLY {0,1}(5)
EXACT </> can match 0 times out of 1...
13 <path/to/dir/> <> | 5: SEOL(6)
13 <path/to/dir/> <> | 6: END(0)
這是因爲$
是零寬度位置錨。如果沒有匹配,\/?
也是如此。一旦模式一直消耗到尾部/
並替換..然後正則表達式引擎繼續(因爲你告訴它與/g
),並找到只剩$
,因爲這仍然是行的末尾。這仍然是一個有效的替代。
但是,爲什麼不改用File::Spec
:
#!/usr/bin/env perl
use strict;
use warnings;
use File::Spec;
use Data::Dumper;
my $path = '/path/to/dir/';
my @dirs = File::Spec->splitdir($path);
print Dumper \@dirs;
$path = File::Spec->catdir(@dirs, "new");
print $path;
這爲您提供了拆分和聯接路徑元素一個獨立於平臺的方式,並且不依賴於正則表達式匹配 - 這有各種方式就可以打破(如你找到的那個)。
謝謝。這工作。你能解釋發生了什麼嗎? – ewok
'$'不會消耗「字符串的結尾」,它只是一個斷言(它聲稱「字符串的末尾在這裏」)。所以用'/?',你的正則表達式在兩個位置匹配:首先匹配'/'後跟行尾,然後如果匹配* nothing *緊跟行尾。明白了嗎? – Dada
排序,但爲什麼不會導致無限循環? – ewok