/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
'$'は "end of string"を消費しません。単なるアサーションです( "文字列の終わりはここにあります")。だから、 '/? 'では、あなたの正規表現は2つの位置でマッチします。最初は'/'に続いて行の終わりにマッチします。それは明確ですか? – Dada
一種ですが、なぜそれが無限ループにならないのですか? – ewok