정규식에서 다음과 같은 항목을 검색하고 싶습니다.
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(
그 앞에는 최소한 하나의 단어 문자가 옵니다.
something.
something
is 앞에 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
경고하다
동일한 줄에서 두 번 발생 하면 some_function_name.foo()
첫 번째 인스턴스만 캡처됩니다.
확실하게 잡고 싶다면모두이러한 패턴의 경우 같은 줄에 두 번 나타나더라도 다음을 사용할 수 있습니다.
grep -Po '\w*(?=\.foo\(\))'
설명하다:
남자 grep에서 :
-피,--perl-정규식
패턴을 Perl 호환 정규식(PCRE)으로 해석합니다. 이는 실험적이며그렙 -P구현되지 않은 기능에 대해 경고할 수 있습니다.
-영형,--일치만
일치하는 줄의 일치하는(비어 있지 않은) 부분만 인쇄하며, 각 부분은 별도의 출력 줄에 표시됩니다.
이 섹션을 (?=\.foo\(\))
호출하면 Lookahead
패턴에서 부분적으로 일치하는 텍스트를 제거할 수 있습니다. 그래서 이 경우에는 .foo()
패턴에서 나올 것입니다 .