8

最近 X/Motif から Qt に移動された C++ コード ベースに取り組んでいます。Boolean (X から) をすべて bool に置き換える Perl スクリプトを作成しようとしています。スクリプトは単純な置換を行うだけです。

s/\bBoolean\b/bool/g

いくつかの条件があります。

1) コードに CORBA があり、\b は CORBA::Boolean に一致しますが、これは変更しないでください。
2) 文字列 (つまり、「ブール値」) として見つかった場合は一致しないはずです。

更新しました:

#1 では、後読みを使用しました

s/(?<!:)\bBoolean\b/bool/g;

#2 では、先読みを使用しました。

s/(?<!:)\bBoolean\b(?!")/bool/g</pre>

これは私の状況ではうまくいく可能性が高いですが、次の改善はどうですか?

3) 文字列の途中にある場合は一致しません (thanks nohat )。
4) コメントの場合は一致しません。(// また /**/)

4

9 に答える 9

3

s/[^:]\bブール値\b(?!")/bool/g

これは、[^:] が「: 以外の文字に一致する」ため、ブール値が行頭にある文字列には一致しません。

于 2008-08-29T20:20:09.697 に答える
2

その引用一致先読みアサーションに気をつけてください。Booleanが文字列の最後の部分である場合にのみ一致しますが、文字列の途中では一致しません。文字列に含まれていないことを確認したい場合は、一致の前に偶数個の引用符を一致させる必要があります (複数行の文字列やエスケープされた埋め込み引用符がないことを前提としています)。

于 2008-08-29T21:36:34.457 に答える
1
#define Boolean bool

前処理者にこれを任せてください。ブール値が表示されるたびに、手動で修正するか、正規表現で間違いがないことを期待できます。使用するマクロの数に応じて、cppからダンプすることができます。

于 2008-09-18T18:13:00.860 に答える
1
s/[^:]\bBoolean\b[^"]/bool/g

編集: ネズミ、また殴られた。私を殴ったことで+1、いいですね。

于 2008-08-29T20:12:20.620 に答える
0

Perlで完全なCパーサーを作成することを避けるために、バランスをとろうとしています。変更する必要のある量に応じて、非常に制限的なs ///のようなことをする傾向があります。その後、/ Boolean /に一致するものはすべて、人間の意思決定のために例外ファイルに書き込まれます。そうすれば、存在する可能性のあるCの中間文字列、複数行コメント、条件付きコンパイル済みテキストなどを解析しようとはしません。

于 2008-09-17T19:20:53.263 に答える
0

3)文字列の途中にある場合は一致しないでください(nohatに感謝)。

おそらく、「。*Boolean。*」をチェックするための正規表現を書くことができます。しかし、文字列内にquote( ")がある場合はどうなるでしょうか?したがって、(\")パターンを除外しないようにするための作業が増えます。

4)コメントの場合は一致しないでください。(// また /* */)

'//'の場合、//。*を除外する正規表現を使用できます。ただし、最初に正規表現を配置して、//コメント((。*)(//。*))との行全体を比較することをお勧めします。次に、$ 1(最初に一致するパターン)にのみ置換を適用します。

/ * * /の場合、これは複数行のパターンであるため、より複雑になります。1つのアプローチは、最初にコード全体を実行して複数行のコメントに一致させ、次に一致しない部分のみを取り出すことです...(。*)(/*.**/)(.*)のようなものです。ただし、実際の正規表現は、1つではなく複数行のコメントがあるため、さらに複雑になります。

さて、//ブロック内に/*または*/がある場合はどうなりますか?(なぜあなたがそれを持っているのか分かりませんが..しかしマーフィーの法則はあなたがそれを持っていることができると言っています)。明らかにいくつかの方法がありますが、私の考えは、正規表現がどれほど見栄えが悪くなるかを強調することです。

ここでの私の提案は、C ++用の字句ツールを使用し、トークンBooleanをboolに置き換えることです。あなたの考え?

于 2008-09-04T13:14:28.873 に答える
0

「文字列の途中にある「ブール値」」の部分は少しありそうにないように聞こえます。最初に、コード内に次のようなものが出現するかどうかを確認します。

m/"[^"]*Boolean[^"]*"/

そして、まったくまたは少数の場合は、その場合を無視してください。

于 2008-09-18T00:35:43.757 に答える
0
  1. …</li>
  2. …</li>
  3. 文字列の途中にある場合は一致しないでください(nohatに感謝)。
  4. コメント内の場合は一致しません。(// また /**/)

単純な正規表現ではできません。そのためには、実際にすべての文字を左から右に見て、それがどのようなものであるかを判断する必要があります。少なくとも、他のものからの文字列からの複数行のコメントからコメントを区別するのに十分です。 「その他」の部分に変更したいものが含まれているかどうかを確認します。

さて、C ++でのコメントと文字列の正確な構文規則がわからないので、以下は不正確で完全にデバッグされないでしょうが、それはあなたが直面している複雑さのアイデアをあなたに与えるでしょう。

my $line_comment      = qr! (?> // .* \n? ) !x;
my $multiline_comment = qr! (?> /\* [^*]* (?: \* (?: [^/*] [^*]* )? )* )* \*/ ) !x;
my $string            = qr! (?> " [^"\\]* (?: \\ . [^"\\]* )* " ) !x;
my $boolean_type      = qr! (?<!:) \b Boolean \b !x;

$code =~ s{ \G (
      $line_comment
    | $multiline_comment
    | $string
    | ( $boolean_type )
    | .
) }{
    defined $2 ? 'bool' : $1
}gex;

これをすべての複雑さで説明するように私に頼まないでください、それは私に1日ともう1日かかるでしょう。ここで何が起こっているのかを正確に理解したい場合は、JeffFriedlのMasteringRegularExpressionsを購入して読んでください。

于 2008-09-17T19:49:28.983 に答える
0

条件 1 を修正するには、次を試してください。

s/[^:]\bBoolean\b(?!")/bool/g

[^:] は、":" 以外の任意の文字に一致することを示します。

于 2008-08-29T20:11:28.967 に答える