正規表現を使用した関数名の前の関数文字列の抽出

正規表現を使用した関数名の前の関数文字列の抽出

正規表現で次の項目を検索したいと思います。

package_name.some_function_name.foo()  

これは行の一部になり、抽出されますが、some_function_name次のように機能する必要があります。

if(some_function_name.foo()){  

それがpackage_nameなくなった

私は試した:

git grep -h foo | perl -pe 's/.*\w.*(package_name[.])?(.*_.*)[.]foo.*/$2/'  

しかし、うまくいきません

これ以外に、sedのようなより良い方法があれば、perl私も同意します。

答え1

あなたの.*\w.*(package_name[.])?(.*_.*)[.]foo.*正規表現は単語文字を含む行と一致し、次にa(オプションであるため_言及しませんでした)、。最後に表示される前の最後の単語文字とその間の内容をキャプチャします。package_name..foo$2_.foo.foo

例えば、

asd().x_y + x.foo() + blah_x++ - _x.foobar
                           ^^^^^^^^

その後、s///一致する行は全行に置き換えられますが(正規表現が全行と一致するため)、他の行は変更されずに残ります。

代わりに、次のようにすることができます。

perl -lne 'print for /(\w+)\.foo\(/g'

各項目の前の一連の単語文字を抽出し、.foo(その前に少なくとも1つの単語文字が続きます。

something.somethingisの前にaがある場合にのみ、その単語文字シーケンスを許可するには、package_name次のようにします。

perl -lne '
  while (/(\w+\.)?(\w+)\.foo\(/g) {
    print $2 if !$1 || $1 eq "package_name.";
  }'

または以下も除外しますother.package_name.foo()

perl -lne '
  while (/((?:\w+\.)*)(\w+)\.foo\(/g) {
    print $2 if !$1 || $1 eq "package_name.";
  }'

答え2

before文字列を探していると仮定すると、.foo()次のことを試すことができます。

sed 's/^.*\W\(\w*\)\.foo().*$/\1/g'
説明する:
  • 記号\wは同義語です。[_[:alnum:]]
  • 記号\Wは同義語です。[^_[:alnum:]]

.foo()だから私たちは文字が前に来て、文字だけで構成された古い部分を探しています。この部品だけで生産ライン全体を交換します。alphanumeric_non-alphanumeric

警告する

同じ行で2回発生すると、some_function_name.foo()最初のインスタンスのみがキャプチャされます。

確実に握りたいならみんなこれらのパターンでは、同じ行に2回表示されても、次のものを使用できます。

grep -Po '\w*(?=\.foo\(\))'
説明する:

男のgrepから:

-血--perl-正規表現

パターンをPerl互換正規表現(PCRE)として解釈します。これは実験的です。グレブ-P実装されていない機能について警告できます。

- モールド--一致のみ

一致する行の一致する(空でない)部分のみが印刷され、各部分は別々の出力行に表示されます。

このセクションを(?=\.foo\(\))呼び出すと、Lookaheadパターンから部分的に一致するテキストを削除できます。だからこの場合は.foo()パターンから出るでしょう。

関連情報