2017-03-29 4 views
2

(참고 : Why can't you use repetition quantifiers in zero-width look behind assertions이 아니 중복, 게시물의 끝을 참조하십시오.)부정적인 lookbehind

을 나는 그것이 선행되지 않을 때 B를, 일치하는 grep -P (펄) 정규식을 작성하려고 해요 A - 사이에 공백이 있는지 여부에 관계없이. "AB"일치하는 결과 않습니다이 일치하지 않는 "AB"를 원인

(?<!A)\s*B 

, 좋은,하지만 :

그래서,이 부정적인 lookbehind을 시도하고, regex101.com에서 테스트 , 그것은 내가 원하는 것이 아닙니다.

이유가 정확히 무엇인지 모르겠습니다. \ s *가 빈 문자열 ""과 일치한다는 것과 관련이 있습니다. A와 B 사이의 \ s *가 무한대로 일치한다고 말할 수 있습니다. 그러나 왜 이것이 "AB"에 영향을 미치지 만 "AB"가 아닌가요?

다음 정규식이 적절한 해결책입니까? 그렇다면 왜 문제가 정확히 해결됩니까?

(?<![A\s])\s*B 

이전에 게시했는데 중복 질문으로 잘못 표시되었습니다. 내가 찾고있는 가변 길이는 일치의 일부이며 부정적인 lookbehind 자체의 일부가 아닙니다. 그래서 이것은 다른 질문과 상당히 다릅니다. 예, 네거티브 lookbehind 안에 \ s *를 넣을 수는 있지만 아직 완료하지 않았습니다. 다른 질문에 설명 된대로 지원하지 않습니다. 또한, 나는 특히 작동에 대해 알고 있기 때문에이 위의 대체 정규 표현식에 대해 왜 에 관심이 있는지 정확히 모르겠다. 다른 질문은 그 대답에 도움이되지 못했습니다.

+0

또한/[^ A \ s] \ s * B /' –

+0

을 사용할 수도 있습니다. 좋은 점 . 내 실제 사용 사례에서 A와 B는 단순한 문자가 아닌 두 단어입니다. – wdep1

+1

'(? sln

답변

4

하지만 왜 이것이 "AB"가 아닌 "AB"에 영향을 줍니까? 이 문자 사이 인 것으로 생각하는 것이 도움이되는 위치에서

정규 표현식에 일치합니다. "AB"에는 (?<!A)이 성공하는 위치 (바로 앞에 A가 없기 때문에 공간이 있음)와 \s*B이 성공합니다 (\s*은 공 문자열과 일치하고 B은 일치합니다). B), 전체 패턴이 성공합니다.

"AB"에는 이러한 위치가 없습니다. \s*B이 (B 바로 앞에) 일치 할 수있는 유일한 장소는 A의 바로 뒤에 있으므로 (?<!A)은 성공할 수 없습니다. 두 가지를 모두 만족하는 위치는 없으므로 패턴 전체가 성공할 수 없습니다.

다음 정규식이 적절한 해결책입니까? 그렇다면 왜 문제가 정확히 해결됩니까?

(?<![A\s])\s*B

(?<![A\s]) 공백 후에는 A 또는 후 즉시 성공하지 않기 때문 작동

. 이제 lookbehind는 앞에 공백이있는 일치 위치를 금지합니다. 이 B보다 앞에 공백 인 경우이면 패턴의 \s* 부분에 의해 소비되어야하며 일치 위치는 앞에 위치해야합니다.해당 위치 앞에 A가 없으면 lookbehind가 성공하고 패턴 전체가 일치 할 수 있습니다.

\s에서 비어 있지 않은 \s* 경기 내 모든 위치와 일치 고정 폭 패턴이라는 사실에 의해 가능하게있어 속임수입니다. 의 일반적인 경우로 확장 할 수 없습니다. (비 A) A와 B 사이의 패턴이 모두입니다.

+0

의미가 있습니다. 고마워요! Re : 첫 번째 요점 : "(< wdep1

+0

요약하면, 이것을 읽고 혼란스럽게 생각하는 사람은 누구나 : 원래 정규 표현식의 경우 "AB"는 까다로운 경우입니다. 왜냐하면 \ s *가 빈 문자열처럼 작동하고 앞의 공백이 아닌 B보다 먼저 일치 할 가능성이 있기 때문입니다. 선행 A이므로 음수 lookbehind는 일치를 금지하지 않습니다. 이 문제를 해결하기 위해 정규 표현식을 변경하면 공백 바로 뒤에없는 일치하는 위치 만 고려 될 수 있습니다. – wdep1

+0

@ wdep1 유효한 포인트! 나는 "일치"를 "성공"으로 바꿨는데, 이는 분명히 명확하다 (어떤 것도 매치하지 않으면 부정적인 검색이 성공한다). – hobbs

관련 문제