1

Perl でファイル フルネームのディレクトリ部分を置き換えようとしています。次のようなものです: ディレクトリ 'D:\Texts1' にファイル名 'D:\Texts1\text1' があり、それを 'D:\Texts2' に置き換えたい場合、ファイル名は 'D:\Texts2\text1' になります。

私はこのコードを試します:

$filename = 'D:\Texts1\text1';
$i = 'D:\Texts1';
$o = 'D:\Texts2';
$filename =~ s'$i'$o'g;

そして、それは有効になりません。$filename は変更されません。私は次のようなものを使用しようとしました

$i = quotemeta('D:\Texts1');

しかし、それも有効になっていません。

4

6 に答える 6

2

ここにはいくつかの有効な回答があります。この投稿を読みやすくするために、私と一緒に包括的な回答をまとめたいと思います。

根本的な原因

$i = 'D:\Texts1';

正規表現パターンとして使用する場合、「\」はエスケープする必要があります。正規表現エンジンが必要とするのは、D:\\Texts1のような最終的な形式です。したがって、これは機能しませんが、以下に示すように、この形式を構築するには少なくとも 4 つの異なる方法があります。

また、' が一致ステートメントまたは置換ステートメントの区切り文字として使用されている場合、変数補間が無効になり、$filename =~ s'$i'$o'g;がレンダリングされます。ほとんど役に立たない。最初のステップとして、/ または {} を使用するように変更します

解決策 1

quotemetaを使用すると、「\」が効果的にエスケープされます。

$filename = 'D:\Texts1\text1';
$i = quotemeta('D:\Texts1');
$o = 'D:\Texts2';
$filename =~ s/$i/$o/g;

解決策 2

\Q .. \E を使用します。これは quotemeta と同様の効果があります。

$filename = 'D:\Texts1\text1';
$i = 'D:\Texts1';
$o = 'D:\Texts2';
$filename =~ s/\Q$i\E/$o/g; # or s/\Q$i/$o/g also works

解決策 3

文字列内の「\」を明示的にエスケープし、qrを使用して文字列を正規表現パターンとして引用します。

$filename = 'D:\Texts1\text1';
$i = qr 'D:\\Texts1';
$o = 'D:\Texts2';
$filename =~ s/$i/$o/g;

解決策 4

文字列が正規表現の準備ができている範囲でエスケープします。

$filename = 'D:\Texts1\text1';
$i = 'D:\\\\Texts1';
$o = 'D:\Texts2';
$filename =~ s/$i/$o/g;
于 2012-08-17T16:16:19.807 に答える
1

イン\D:\Texts1問題です。このメタキャラクターをエスケープする必要があります。この目的のために、文字列は と でラップする必要が\Qあり\Eます。

$filename =~ s/\Q$i\E/$o/g;
于 2012-08-17T14:20:22.817 に答える
1

これは補間しません

$filename =~ s'$i'$o'g;

次のよう/に の代わりに使用してみてください。'

$filename =~ s/$i/$o/g;

それはうまくいくはずです。'文字列補間を防止するため、変数名は文字列リテラルとして表示されます。また、quotemeta以前と同じように使用してください。

于 2012-08-17T14:20:30.967 に答える
0

実際、次の 2 つの問題が組み合わさって発生しています。

  • 一重引用符は、正規表現の区切り文字として有効ですが、特別な意味があります: 変数補間を無効にします。したがって、文字列をリテラル パターンで検索しています$i(警告を有効にしている場合は、これの手がかりが得られます。つまり、変数 $i と $o がプログラムで 1 回しか使用されていないことがわかります)。
  • 他の人が指摘したように、変数内の特殊文字を正規表現演算子として解釈しないようにするために、\Q...\Eコンストラクト orも必要です。quotemeta()
于 2012-08-17T14:48:55.063 に答える
0

追加する必要があります\Q

$filename =~s{\Q$i}{$o};
于 2012-08-17T14:21:16.987 に答える
-1

更新されたコード

use strict;
use warnings qw/all/;

my $filename = 'D:\Texts1\text1';
my $i = 'D:\\Texts1';
my $o = 'D:\\Texts2';
$filename =~ s/\Q$i\E/$o/;

print $filename;

幸せになる!

于 2012-08-17T14:21:34.787 に答える