정규식 부정 미리보기
내 홈 디렉토리에는 Drupal 플랫폼이 포함 된 drupal-6.14 폴더가 있습니다.
이 디렉토리에서 다음 명령을 사용합니다.
find drupal-6.14 -type f -iname '*' | grep -P 'drupal-6.14/(?!sites(?!/all|/default)).*' | xargs tar -czf drupal-6.14.tar.gz
이 명령이하는 일은 drupal-6.14 폴더를 gzips하고 , 포함 된 sites / all 및 sites / default를 제외하고 drupal-6.14 / sites / 의 모든 하위 폴더를 제외합니다 .
내 질문은 정규 표현식에 있습니다.
grep -P 'drupal-6.14/(?!sites(?!/all|/default)).*'
이 표현식 은 제외하려는 모든 폴더를 제외하도록 작동 하지만 이유를 잘 모르겠습니다.
정규식을 사용하여 다음 작업을 수행하는 일반적인 작업입니다.
하위 패턴 x를 포함 하지 않는 문자열을 제외하고 모든 문자열과 일치합니다 . 즉, 하위 패턴을 부정합니다.
나는 이러한 문제를 해결하기위한 일반적인 전략이 부정적인 예견을 사용하는 것을 이해하고 있지만 긍정적이고 부정적인 예견 (앞 / 뒤)이 어떻게 작동하는지 만족스러운 수준으로 이해하지 못했습니다.
수년 동안 나는 그들에 대한 많은 웹 사이트를 읽었습니다. PHP 및 Python 정규식 설명서, http://www.regular-expressions.info/lookaround.html 등과 같은 다른 페이지가 있지만 실제로 는 제대로 이해 하지 못했습니다 .
누군가 이것이 어떻게 작동하는지 설명하고 비슷한 일을 할 유사한 예를 제공 할 수 있습니까?
-업데이트 하나 :
Andomar의 응답과 관련하여 : 이중 부정 예측이 단일 긍정적 예측 진술로 더 간결하게 표현 될 수 있습니까?
즉 :
'drupal-6.14/(?!sites(?!/all|/default)).*'
다음과 동일 :
'drupal-6.14/(?=sites(?:/all|/default)).*'
???
-업데이트 2 :
@andomar 및 @alan moore에 따라 이중 부정 예측을 긍정적 예측으로 바꿀 수 없습니다.
부정적인 예견은이 위치에서 다음 정규식이 일치 할 수 없음을 말합니다.
간단한 예를 들어 보겠습니다.
a(?!b(?!c))
a Match: (?!b) succeeds
ac Match: (?!b) succeeds
ab No match: (?!b(?!c)) fails
abe No match: (?!b(?!c)) fails
abc Match: (?!b(?!c)) succeeds
마지막 예는 이중 부정입니다 . a b
뒤에 c
. 중첩 된 네거티브 미리보기는 긍정적 인 미리보기가됩니다 c
.
각 예에서 만 a
일치합니다. 미리보기는 조건 일 뿐이며 일치하는 텍스트에 추가되지 않습니다.
둘러보기는 중첩 될 수 있습니다.
따라서이 정규식은 "/ all"또는 "/ default" 가 뒤 따르지 않는 "sites"가 뒤 따르지 않는 "drupal-6.14 /"와 일치 합니다.
혼란 스럽습니까? 다른 단어를 사용하여, 우리는 일치 말할 수있다 "드루팔-6.14 /"입니다 하지 "사이트"다음에 하지 않는 것을 추가로 "/ 모든"또는 "/ 기본"뒤에
다음과 같이 정규식을 수정하면 :
drupal-6.14/(?=sites(?!/all|/default)).*
^^
... 그런 다음 뒤에 또는 이외의 것이drupal-6.14/
뒤에 오는 모든 입력과 일치합니다 . 예를 들면 :sites
/all
/default
drupal-6.14/sites/foo
drupal-6.14/sites/bar
drupal-6.14/sitesfoo42
drupal-6.14/sitesall
원래 정규식과 일치 ?=
하도록 ?!
로 변경하면 해당 일치가 무효화됩니다.
drupal-6.14/(?!sites(?!/all|/default)).*
^^
그래서,이 단순히 것을 의미 drupal-6.14/
지금 할 수없는 뒤에는 sites
다음 이외의 /all
나 /default
. 이제 이러한 입력은 정규식을 충족합니다.
drupal-6.14/sites/all
drupal-6.14/sites/default
drupal-6.14/sites/all42
But, what may not be obvious from some of the other answers (and possibly your question) is that your regex will also permit other inputs where drupal-6.14/
is followed by anything other than sites
as well. For example:
drupal-6.14/foo
drupal-6.14/xsites
Conclusion: So, your regex basically says to include all subdirectories of drupal-6.14
except those subdirectories of sites
whose name begins with anything other than all
or default
.
ReferenceURL : https://stackoverflow.com/questions/1749437/regular-expression-negative-lookahead
'Development Tip' 카테고리의 다른 글
PHP에서 현재 함수를 실행하는 코드 줄과 파일을 얻습니까? (0) | 2021.01.06 |
---|---|
표준 Java API 만있는 javax.xml.transform.Transformer의 예쁜 인쇄 출력 (들여 쓰기 및 문서 유형 위치 지정) (0) | 2021.01.06 |
새 항목이 추가 될 때 ListBox 자동 스크롤을 어떻게 할 수 있습니까? (0) | 2021.01.06 |
C #에서 다차원 배열의 행 / 열 길이를 얻는 방법은 무엇입니까? (0) | 2021.01.05 |
UIButton의 이미지 및 중앙 텍스트 왼쪽 정렬 (0) | 2021.01.05 |