perlの置換のこと
[上に]
[前に]
[次に]
和弘
2000/06/11(日) 17:26:42
aaabbbcccaaadddccc の中から bbb を取り出したいのですが、
s/aaa(.*)ccc/$1/ では bbbcccaaaddd になってしまいます。
最初に見つかった「閉じパターン」まででマッチングさせるにはどうしたらいいのでしょうか?
最後の/のあとに何か書けばいいと思うのですが・・・
S-pore
[HomePage]
2000/06/11(日) 17:32:45
Perl5 なら,
(.*) → (.*?)
とすればええぢゃろう。
Perl4 ではどうやるのが一番いいですか?(便乗質問)
anno
2000/06/11(日) 17:48:49
/aaa([^c]*)ccc/
手元にPerl4ないから確認とれず。
日本語とか入っちゃうとダメだったような気も。
S-pore
[HomePage]
2000/06/11(日) 17:53:50
> /aaa([^c]*)ccc/
これだと,"aaabcbccc" にマッチしてくれませんよね?
S-pore
[HomePage]
2000/06/11(日) 18:22:08
私が考えたやつでは・・・
1 while (s|aaa(.*)|$1 =~ /ccc/; $` . $'|e);
これで,Perl5 の
s/aaa(.*?)ccc/$1/g;
と同じ動作をしてくれると思うんですが,
もっとエレガントな方法がないものか・・・。
Coo
2000/06/11(日) 18:24:11
cも抜きたいんだったらマッチした部分でさらにマッチングとか?
while (($a =~ /(ccc.*)ccc/)) {
$a = $1;
}
$a =~ s/ccc//;
効率悪そうだなぁ(笑)
S-pore
[HomePage]
2000/06/11(日) 18:33:30
> 1 while (s|aaa(.*)|$1 =~ /ccc/; $` . $'|e);
おっと,これだと,"aaabbb" なんて場合まずいですね。
みゅぅ。(謎)
S-pore
[HomePage]
2000/06/11(日) 18:42:20
1 while (s|aaa(.*)ccc|$a = $1; ($a =~ /ccc/) ? ($` . $' . 'ccc') : $a|eg);
なんかえらいことになってしまった。(^^;
もっと簡単な方法ないかなー。
S-pore
[HomePage]
2000/06/11(日) 18:55:54
> aaabbbcccaaadddccc の中から bbb を取り出したいのですが、
というだけなら,
$_ = (/aaa/ && $' =~ /ccc/) ? $` : "";
でいけるんですけどねぇ・・・。
sadahiro
2000/06/11(日) 21:54:09
要するに "aaa" を開始タグ、"ccc" を終了タグとするのですね。
Perl4使ったことないのでなんですが、
本で "×4" と書いてないのだけ使ってみました。
$ini_tag="aaa";
$fin_tag="ccc";
$a ="aaabbbcccaaadddccc";
while ($a =~ m/$ini_tag/g) {
pos $a = $ini_pos = pos $a;
if ($a=~ m/$fin_tag/g){
pos $a = $fin_pos = pos $a;
push @matched, substr($a, $ini_pos, $fin_pos-$ini_pos-length $fin_tag);
} else {last}
}
sadahiro
2000/06/11(日) 22:08:07
追加。
pos $a = への代入は要らないようですね。
S-pore
[HomePage]
2000/06/11(日) 22:19:08
pos って,Perl4 では使えなかったような・・・。
sadahiro
2000/06/11(日) 22:20:32
「取り出す」とは削除するということでしたか、失礼しました。
$ini_tag="aaa";
$fin_tag="ccc";
$a ="aaabbbcccaaadddccc";
if ($a =~ m/$ini_tag/g) {
$ini_pos = pos $a;
if ($a=~ m/$fin_tag/g){
$fin_pos = pos $a;
$a = substr($a,0,$ini_pos) . substr($a, $fin_pos-length $fin_tag);
}
}
これで $a は "aaacccaaadddccc" になるのですが…
sadahiro
2000/06/11(日) 22:21:41
済みません、いずれにせよPerl4で確かめた訳ではないので.
おーなーしぇふ
2000/06/12(月) 01:23:23
>aaabbbcccaaadddccc の中から bbb を取り出したいのですが、
結果がどのようになればよいのかわかりにくいのですが(^^;)
「s/aaa(.*)ccc/$1/」を見る限り、aaabbbccc→bbbにしたいと
思うのですが、流れを見ると「削除」ということなので、
とりあえず「aaacccaaadddccc」という結果で良いなら:
いったんcccを「一文字」に置き換えて処理し、再度元に戻す
ようにすれば、うまくいくのではないかと……。
例)
$str = "aaabbbcccaaadddccc";
$tmp = "\t"; #タブ記号一文字で置き換え
$str =~ s/ccc/$tmp/g; #いったん置き換え
$str =~ s/(aaa)([^$tmp]*)($tmp)/$1$3/;
$str =~ s/$tmp/ccc/g; #置き換えを元に戻す
print "\$str:$str\n"; #結果表示
ちなみにaaaとcccで挟まれた文字列をすべて取り出すのなら、
つまり「ddd」も削除するなら、
$str =~ s/(aaa)([^$tmp]*)($tmp)/$1$3/g;
と、gを付けると良いです。
[上に]
[前に]
[次に]