これは私を戸惑う
次のように常に追加する必要がある変数を持つ大きなCソースファイルがあります。
CycleCounter += SomeValue
一部の値は重要ではありません。
数千行のソースファイルには、このような数百行のコードがあります。すべての割り当てが追加され、予期しない割り当てまたは減算が行われるように努めています。
「+」またはいくつかのスペースと「+」が後に来ないすべてのCycleCounterエントリを探したいです。
私は次のような表現を試してみました。
CycleCounter\s*[^+]
ただし、この場合は「+」が表示される場所も一致します。
これはケース1とも一致しますが、後続の「+」なしでケース2と3のみを一致させたいです。
if (postbyte & 0x80)
{
switch (postbyte & 0x1F)
{
case 0: // Post inc by 1
ea = (*xfreg16[Register]);
(*xfreg16[Register])++;
CycleCounter+=NatEmuCycles21; // good. expression correctly ignored this
break;
case 1: // post in by 2
ea = (*xfreg16[Register]);
(*xfreg16[Register]) += 2;
CycleCounter += NatEmuCycles32; // good. expression incorrectly identified
break;
case 2: // pre dec by 1
(*xfreg16[Register]) -= 1;
ea = (*xfreg16[Register]);
CycleCounter -= NatEmuCycles21; // mistake, subtracted. expression correctly identified
break;
case 3: // pre dec by 2
(*xfreg16[Register]) -= 2;
ea = (*xfreg16[Register]);
CycleCounter = NatEmuCycles32; // mistake, assigned. expression correctly identified
break;
case 4: // no offset
ea = (*xfreg16[Register]);
break;
答え1
PCRE(Perl Compatible Regular Expressions)を使用している場合、このアドインは空白のないアイテムを貪欲に一致させ、空白の一致を防ぎます+
。例えば。 PCRE(GNU grepオプション)を使用して行番号を表示するには、withを使用します。\s*
[^+]
grep
-P
-n
grep -Pn 'CycleCounter\s*+[^+]' file
別のPCRE:
grep -Pn 'CycleCounter(?!\s*\+)' file
今回は否定的な予測を使用して指定されますnot followed a '+' or some white space and a '+'
。
sed
以下を使用して、出力から不要な行を削除できます。
sed '/CycleCounter/!d; /CycleCounter[[:space:]]*+/d; =' file
CycleCounterを含まない行を削除し、CycleCounterの後にスペースと「+」を含む行も削除します。=
行番号を印刷します。
答え2
それは*
量子についてです。\s*
- これは、一致するものがない可能性があることを意味します。 2番目の式[^ +]は、単語の直後の空白文字と一致しますCycleCounter
。
grep 'CycleCounter\s\+[^+]'
または
grep 'CycleCounter\s*[^+]='
または
grep 'CycleCounter\s*[^+ ]'
答え3
CycleCounter
前提を一致させたい場合いいえオプションのスペース sum の後に+
Perl の否定予測演算子を使用できます。
grep -P 'CycleCounter(?!\s*\+)'
(これはPerlに似た正規表現をgrep
サポートする実装を想定しています)。-P
CycleCounter
後にオプションの空白と+
空白も空白でもない文字が続く場合、一致させたい場合:
grep 'CycleCounter[[:space:]]*[^+[:space:]]'
[[:space:]]
Perlと同じPOSIX正規表現です\s
。一部の実装ではこれをBRE / EREの拡張としてgrep
もサポートしていますが、または括弧内の式内の一致のPOSIX要件をサポートしていません。\s
[\s]
\
s
いずれにせよ、[[:space:]]
および\s
は改行と一致しますが、デフォルトではgrep
一度に1行の内容のみが処理されるため(改行区切り文字を除く)、両方とも次の最初の行と一致します。
CycleCounter
+= 12;
例えば。
PCRE(Perlに似た正規表現を実装し、オプションをサポートするほとんどの実装で使用されるライブラリであるpcregrep
PCREに付属)を使用すると、次のことができます。grep
-P
pcregrep -M '(?s)CycleCounter(?!\s*\+).*?;'
ここでは-M
、複数行モードを有効にし、改行でも一致を(?s)
引き起こし、完全なC文が次の文字で印刷されるようにします。.
.*?;
;
もちろん、まだ次のようなものに騙されます。
CycleCounter // blah ;
+= (c == ';')
+ 3;
また彼らはで一致することに注意して下さいMyCycleCounter2 += 3
。これを防ぐには、周囲に単語境界演算子を追加するだけですCycleCounter
。 Perlには同等のPOSIX正規表現はありませんが、\bCycleCounter\b
いくつかのgrep
実装ではまたは拡張をサポートして\b
います。\<CycleCounter\>
[[:<:]]CycleCounter[[:>:]]