Development Tip

정규식 부정 미리보기

yourdevel 2021. 1. 6. 20:28
반응형

정규식 부정 미리보기


내 홈 디렉토리에는 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

반응형