perl regex - (\s*//\s*)로 시작하지 않는 foobar를 일치시키는 방법

perl regex - (\s*//\s*)로 시작하지 않는 foobar를 일치시키는 방법

기본적으로 다음과 같이 주석 처리되지 않은 줄에서 foobar를 찾고 싶습니다.

// foobar      # do not match me
 foobar        # match me
 otherfoobar   # do not match me

주석 줄을 일치시키기 위해 다음을 사용합니다.^(\s*//\s*)\bfoobar\b.*$

주석 처리되지 않은 줄을 일치시키는 방법은 무엇입니까?

노트:

불필요한 노력을 피하려면 답변을 "^...$"로 제한하세요. 이는 일치를 위해 Perl로 전송된 문자열 내에서만 수행되어야 합니다.

또한 foobar는 \bfoobar\b와 같이 전체적으로 일치해야 합니다.

마지막으로, \bfoobar\b 앞에는 공백이나 주석 서명을 제외한 어떤 문자도 와서는 안 됩니다.

답변1

foobara의 오른쪽에 a가 없으면 다음 //과 같이 표현될 수 있습니다.

^(?:(?!//).)*\bfoobar\b

*이는 0개 이상의 ( ) 문자( )로 구성된 시퀀스입니다. 각 문자는 .시퀀스의 시작 부분에 있지 않으며( ) 그 뒤에 단어 경계로 구분된 문자가 옵니다.//(?!//)foobar

답변2

Perl 호환 정규식을 사용하는 도구가 아닌 Perl(언어)을 사용하는 경우 하나의 정규식으로만 제한할 이유가 없습니다.

다음과 같은 내용은 주석 처리되지 않은 줄에만 일치합니다.

$ perl -ne 'print if not m,^\s*//, and /\bfoobar\b/' < file.txt 
 foobar        # match me

다른 유틸리티나 Perl이 아닌 정규식을 사용하는 경우에도 여러 정규식을 사용하는 것이 가장 쉽습니다.

$ < file.txt grep -ve '//' | grep '\<foobar\>'
 foobar        # match me

대신, 단일 Perl 정규식으로 제한되는 경우 다음이 작동합니다.

grep -P '^\s*+(?!//).*\bfoobar\b.*$' file.txt

이것은\s*+"소유" 표현, 모든 선행 공백과 일치하며그들을 보내지 마세요. 그런 다음 (?!//)선행 공백 뒤에 오는 내용이 주석 표시가 아닌지 확인하고 마지막으로 foobar줄 어디에서나 하이픈을 찾습니다.

(소유 한정자 없이 공백이 일치하는 경우 정규식 엔진은 선행 공백에서 종료되고 잘못된 위치에 있는 주석 표시를 확인하여 주석 행이 일치되도록 할 수 있습니다.)

테스트 데이터:

$ cat file.txt
 // foobar        # do not match
 foobar           # 1st match
otherfoobar       # do not match
something foobar  # 2nd and final match
$ grep -P '^\s*+(?!//).*\bfoobar\b.*$' file.txt
 foobar           # 1st match
something foobar  # 2nd and final match

답변3

부정의 문제가 지나치게 복잡해질 필요는 없다고 생각합니다.

예를 들어 다음 행을 거부하고 싶다고 가정해 보겠습니다.

"^(\s*//\s*).*(\bfoobar\b).*$"

즉. '//'시작 여백에 주석 서명을 넣고 그 뒤에 'foobar'전체 단어가 포함된 내용이 옵니다(명확성을 위해 대괄호 포함).

이를 부정하려면 다음을 수행합니다.

"^(?!\s*//\s*).*(\bfoobar\b).*$"

우리는 그것을 다음 (\s*//\s*)과 같이 대체합니다.(?!\s*//\s*)

'//'이는 시작 부분의 공백에 주석 서명이 있고 그 뒤에 패턴이 있는 모든 항목을 무시합니다.

결과:

  // foobar will not be matched
  // whatever foobar will not be matched
  foobar will be matched
  whatever foobar will be matched
  whateverfoobar will not be matched

노트:.*이전 설정을 변경하여 더욱 세부적으로 조정할 수 있습니다 (\bfoobar....

예를 들어 나는 할 수 있다"^(?!\s*//\s*)\s*(\bfoobar\b).*$"

  foobar will be matched
  whatever foobar will **NOT** be matched

경고하다:'foobar'위의 방법을 시도 하는 것처럼 임의의 문자열로 바꾸면 '${foobar}'실패합니다. 그 이유는 일반적인 "foobar"가 단어 문자로만 구성되어 있기 때문에 이제는 (\bfoobar\b)일치하지 않기 때문입니다. 이 경우 \b제거가 필요합니다.

관련 정보