2

JCL スクリプトでジョブ名を置き換える Perl 関数を作成しました。ここではゼロ幅一致が使用されました。

sub modify_jcl_jobname ()
{
    my ($jcl, $old, $new) = @_;

    $jcl =~ s/
         # The name must begin in column 3.
         ^(?<=\/\/)     

         # The first charater must be alphabetic or national.
        ($old)

         # The name must be followed by at leat on blank.
         # Append JCL keyword JOB 
        (?=\s+JOB)
       /$new/xmig; # Multi-lines, ignore case.

    return $jcl;
}

しかし、先頭の記号「^」を削除するだけの簡単な変更を行うまで、この機能は機能しませんでした。

  #before  ^(?<=\/\/) 

  #after    (?<=\/\/) 

そのため、問題の原因を明確にしたいと思います。返信をいただければ幸いです。ありがとう。

4

2 に答える 2

8

問題はにあります

^(?<=\/\/)

そのパターンは、^一致した後のスポットの前に2つの文字がある場合にのみ一致し//ます。/^/m文字列の先頭と改行の後に一致するため、これは発生しません。

ただし、行の先頭からマッチングを開始する必要はありません。で2文字の照合を開始します。実際に必要なのは次のとおりです。

(?<=^\/\/)

いくつかの改善を行った後、コードは次のようになります。

sub modify_jcl_jobname {
    my ($jcl, $old, $new) = @_;
    $jcl =~ s{
         (?<= ^// )
         \Q$old\E
         (?= \s+ JOB )
    }{$new}xmig;

    return $jcl;
}

改善点:

  • 誤ったプロトタイプを削除しました(())。呼び出し元は、Perlにプロトタイプを無視するように強制しました(を使用して&)。
  • \Q...\Eをそのまま使用する前に、の内容を$old正規表現パターンに変換するコード()を追加しました。
  • 不要なキャプチャ((...))を削除しました。
  • 置換の区切り文字(から)を切り替えて、s///エスケープs{}{}の必要性を減らしました。
  • 冗長性の高いコメントを削除しました。(良いコメントは、何が行われているのかではなく、なぜ何かが行われているのかを説明しています。)

オプティマイザーは、このバージョンをより適切に処理する可能性があります。

$jcl =~ s{
     ^// \K
     \Q$old\E
     (?= \s+ JOB )
}{$new}xmig;
于 2012-09-06T15:48:46.737 に答える
3

^符号は行頭と一致します。次に、2 つのスラッシュが前にあるものが必要です。次の文字が行の最初の文字である場合、これらのスラッシュはどこに置くべきでしょうか?

s{^//
  ($old)
  ...
 }{//$new}xmig

動作するはずです。後ろを見る必要はありません。

更新: ikegami のおかげで、あなたがそれを使用した理由がわかりました。文字列に を保持したい//場合: 置換でそれらを繰り返すか、^文字を後読みに移動できます。

于 2012-09-06T15:35:39.440 に答える