1

前回の投稿でタグが一部剥がれてしまったので、もう一度。

私の目標は、末尾のすべてのインスタンスをタグブラケット内の末尾の + に置き換えることです。置き換えられる行が次のようになっているとします。

<h> aa- aa- </h> <h> ba- ba- </h> 

その後、次のようになります

<h> aa+ aa+ </h> <h> ba+ ba+ </h>.

まず、この表現を試しました。

s/<h>(.*?)-(.*?)<\/h>/<h>$1+$2<\/h>/g;

この出力が得られました:

<h> aa+ aa- </h> <h> ba+ ba- </h>.

g オプションを使用すると、行ごとに複数の置換が行われますが、タグ ブラケットごとの最初のインスタンスのみです (両方の丸括弧に疑問符が含まれている場合のみ)。

問題を絞り込むために、タグを無視して置換を実現しようとしました。表現

s/(.*?)-(.*?)/$1+$2/g;

実際に望ましい結果につながる

<h> aa+ aa+ </h> <h> ba+ ba+ </h>.

もちろん、これはタグブラケットの外側でも代用されます。

では、最初の式の問題は何ですか? また、タグ ブラケット内で完全に置換するという目標を達成するにはどうすればよいでしょうか?

4

2 に答える 2

0

1) g オプションは、タグを含む正規表現全体に対して機能します

2) 2 回または変化がなくなるまで使用する

于 2010-08-01T12:25:35.533 に答える
0

タグ選択と置換操作を分離します。

$str = '<h> aa- aa- </h> <h> ba- ba- </h>';
while ( $str =~ m!<h>.*?-.*?</h>! ) {
    substr( $str, $-[0], $+[0] - $-[0] ) =~ y/-/+/;
}
print $str, "\n";

(@-および@+配列は、最後に成功した一致に関するオフセット情報を提供します。)

または:

sub fixup_h_tag {
    my $tag = shift;
    $tag =~ y/-/+/;
    $tag
}
$str = '<h> aa- aa- </h> <h> ba- ba- </h>';
$str =~ s{ (<h>.*?</h>) }{ fixup_h_tag("$1") }gxe;
print $str, "\n";

タグ マークアップ言語が何らかのコメントまたは引用符付き文字列 (タグとして含まれているかどうかに関係なく)、またはオプションの空白または h タグの属性を許可している場合、正規表現は堅牢なソリューションを簡単に提供できないことに注意してください。

于 2010-08-01T17:14:30.427 に答える