0

Perl で単純な検索と置換を行っていますが、助けが必要です。これらはファイル内の行です。

1001(seperator could be "anything")john-1001(seperator could be "anything")mark
1001(seperator could be "anything")mark-1001(seperator could be "anything")john

2001 のように、john に新しいユーザー ID を割り当てたいと考えています。これが私が望む結果です。

2001($1)john-1001-mark
1001-mark-2001($1)john

私の正規表現は、ジョンが最初の場合は正常に機能しますが、マークが最初の場合はめちゃくちゃになります。

4

4 に答える 4

3

これを試して:

#!/usr/bin/perl

use strict;
use warnings;

while (<DATA>) {
    s/\b1001-john\b/2001-john/;
    print;
}

__DATA__
1001-john-1001-mark
1001-mark-1001-john
11001-john
1001-johnny

\b、 以外のものとの一致を防ぎ"1001-john"ます。詳細については、「アサーション」セクションを参照しperldoc perlreてください。


うーん、 sexegerが必要なようですね:

#!/usr/bin/perl

use strict;
use warnings;

while (<DATA>) {
    my $s = reverse;
    $s =~ s/\bnhoj(.*?)1001\b/nhoj${1}1002/;
    $s = reverse $s;
    print $s;
}

__DATA__
1001-john-1001-mark
1001-mark-1001-john
11001-john
1001-johnny

セクセジャーの基本的な考え方は、文字列を逆にし、逆の正規表現を使用してから、結果を逆にすることです。問題は、.*?可能な限り短い文字列ではなく、最初の一致から最短の文字列が得られることです。もちろん、これには will が一致するため、まだ問題が"1001-mark-2001-john"あり.*?ます"-mark-2001-"。おそらく、正規表現を使用するよりも、ファイル形式を特定して解析する方がよいでしょう。

于 2009-06-02T20:43:12.900 に答える
3

セパレーターが何であるか、つまりどの文字、何文字かなどを知らずにこれに答えるのはほとんど不可能です。貪欲でない任意のセパレーターは次のようになります。

s/\b1001\b(?=.*?\bjohn\b)/2001/

これは、最小数の中間文字に一致している間、「john」が続く場合に「1001」を置き換えます。.*?の貪欲でないバージョンです.*。ただし、可能であれば正規表現は常に一致するため、これは引き続き一致します

1001-mark-1001-john

言い換えれば、それは貪欲さの問題だけではありません。次の 3 つのうち少なくとも 1 つを定義する必要があります。

  • セパレーターに含めることができる文字。
  • セパレーターに含めることができない文字。
  • セパレータの文字数。

セパレーターに「単語」文字 (az、0-9、およびアンダースコア) を含めることができないと仮定すると、実行可能なものを得ることができます。

s/\b1001\b(?=\W+?\bjohn\b)/2001/

既知の部分 (「1001」と「john」) は、これらの部分文字列と他の文字列が一致しないように制限されています。(エッジケースに気づいてくれた Chas に感謝します。)

于 2009-06-02T20:41:38.470 に答える
0

あなたのコメントから、セパレーターは常にハイフンではなく、実際には複数の文字になる可能性があると推測しています。

この場合、次を試してください。

s/\d+([^\d]*)john/2001$1john/

これにより、置換中に「1001」と「john」の間のセパレーターがそのまま保持されます。セパレータには数字を使用できないため、「マーク」の後に「john」が表示される場合でも機能します (「-mark-1001-」は有効なセパレータではないため)。

于 2009-06-02T20:47:52.607 に答える
-1

それは次のようなものになる可能性があります

$s = '1001-mark-1001-john';
$s =~ s/(\d+)(-john)/2001$2/i;
print $s;
于 2009-06-02T20:44:19.183 に答える