4

私はついに正規表現を学び、ackでトレーニングしています。これはPerl正規表現を使用していると思います。

if (<word> !最初の空白以外の文字が含まれるすべての行を、要素間に任意の数のスペースを入れて一致させたいと思います。

これは私が思いついたものです:

^[ \t]*if *\(\w+ *!

それはほとんど機能しました。^[ \t]*[スペースまたはタブ]の1つまたはまったく一致しないため、間違っています。私が欲しいのは、スペースまたはタブのみ(または何も含まない)を含む可能性のあるものすべてに一致させることです。

たとえば、これらは一致しないはずです。

// if (asdf != 0)
else if (asdf != 1)

そのために正規表現を変更するにはどうすればよいですか?


コマンドラインを追加して編集

ack -i --group -a '^\s*if *\(\w+ *!' c:/work/proj/proj 

一重引用符に注意してください。もうよくわかりません。

私の検索ベースはより大きなコードベースです。一致する式(かなりの数)が含まれていますが、たとえば次のようになります。

274:                }else if (y != 0) 

、上記のコマンドの結果として取得します。


mobruleのテストの結果を追加して編集

Mobrule、テストするテキストを提供してくれてありがとう。プロンプトで得たものをここにコピーします。

C:\Temp\regex>more ack.test
# ack.test
if (asdf != 0)    # no spaces - ok
 if (asdf != 0)   # single space - ok
    if (asdf != 0) # single tab - ok
   if (asdf != 0) # multiple space - ok
        if (asdf != 0) # multiple tab - ok
    if (asdf != 0) # spaces + tab ok
     if (asdf != 0) # tab + space ok
     if (asdf != 0) # space + tab + space ok
// if (asdf != 0)  # not ok
} else if (asdf != 0) # not ok

C:\Temp\regex>ack '^[ \t]*if *\(\w+ *!' ack.test

C:\Temp\regex>"C:\Program\git\bin\perl.exe" C:\bat\ack.pl '[ \t]*if *\(\w+ *!' a
ck.test
if (asdf != 0)    # no spaces - ok
 if (asdf != 0)   # single space - ok
    if (asdf != 0) # single tab - ok
   if (asdf != 0) # multiple space - ok
        if (asdf != 0) # multiple tab - ok
    if (asdf != 0) # spaces + tab ok
     if (asdf != 0) # tab + space ok
     if (asdf != 0) # space + tab + space ok
// if (asdf != 0)  # not ok
} else if (asdf != 0) # not ok

問題は私のack.batへの呼び出しにあります!

ack.batに含まれるもの:

"C:\Program\git\bin\perl.exe" C:\bat\ack.pl %*

気をつけて電話しますが、batファイルの呼び出しで逃げます!

でキャレットをエスケープすること^^はできません。

" "作品の代わりに正規表現を引用し' 'ます。私の問題はDOS/winの問題でした。ご迷惑をおかけして申し訳ありませんが、

4

3 に答える 3

6
^\s*if\s*\(\S+\s*!
  • \S非空白に使用します。\w特殊文字と一致しないため、一致しif ($wordません。あなたの仕様ではそれでいいかもしれません。その場合、\w(英数字と "_" ) は問題ありません
$ perl5.8 -e '{$s="else if (asdf \!= 1)"; if ($s =~ /^\s*if\s*\((\S+)\s*\!/) { print "|$1|\n";} else { print "NO MATCH\n";} }'
歯が立たない
$ perl5.8 -e '{$s="// if (asdf \!= 0)"; if ($s =~ /^\s*if\s*\((\S+)\s*\!/) { print "|$1|\n";} else { print "NO MATCH\n";} }'
歯が立たない
$ perl5.8 -e '{$s=" if (asdf \!= 0)"; if ($s =~ /^\s*if\s*\((\S+)\s*\!/) { print "|$1|\n";} else { print "NO MATCH\n";} }'  
|asdf|
$ perl5.8 -e '{$s="if (asdf \!= 0)"; if ($s =~ /^\s*if\s*\((\S+)\s*\!/) { print "|$1|\n";} else { print "NO MATCH\n";} }'
|asdf|
$ perl5.8 -e '{$s="if (\$asdf \!= 0)"; if ($s =~ /^\s*if\s*\((\S+)\s*\!/) { print "|$1|\n";} else { print "NO MATCH\n";} }'
|$asdf|
于 2010-04-14T15:25:47.037 に答える
4

と の両方ackgrep*0 または 1 ではなく、0 以上に一致します。だから、あなたはすでに正しい解決策を持っていると思います。必要な結果が得られないテスト ケースはどれですか?

# ack.test
if (asdf != 0)    # no spaces - ok
 if (asdf != 0)   # single space - ok
    if (asdf != 0) # single tab - ok
   if (asdf != 0) # multiple space - ok
        if (asdf != 0) # multiple tab - ok
    if (asdf != 0) # spaces + tab ok
     if (asdf != 0) # tab + space ok
     if (asdf != 0) # space + tab + space ok
// if (asdf != 0)  # not ok
} else if (asdf != 0) # not ok

結果:

$ ack '^[ \t]*if *\(\w+ *!' ack.test
if (asdf != 0)    # no spaces - ok
 if (asdf != 0)   # single space - ok
        if (asdf != 0) # single tab - ok
   if (asdf != 0) # multiple space - ok
                if (asdf != 0) # multiple tab - ok
        if (asdf != 0) # spaces + tab ok
         if (asdf != 0) # tab + space ok
         if (asdf != 0) # space + tab + space ok

$ ack -v '^[ \t]*if *\(\w+ *!' ack.test
// if (asdf != 0)  # not ok
} else if (asdf != 0) # not ok
于 2010-04-14T15:43:02.413 に答える
1

あなたが試すことができます:

(?:\t*| *)if *\(\w+ *!

.

\t*| *

スペースとタブの混合ではなく、0 個以上のタブまたは 0 個以上のスペースになります。

于 2010-04-14T15:28:50.797 に答える