정규식과 "역 일치"하는 방법은 무엇입니까?


112

나는 RegexBuddy를 사용하고 있지만 어쨌든이 일에 문제가 있습니다 : \

한 줄씩 파일을 처리하고 있습니다. 내가 원하는 것과 일치하는 "라인 모델"을 만들었습니다.

이제 역 일치를하고 싶습니다. 즉, 6 개의 문자가있는 줄을 일치시키고 싶지만이 6 개의 문자가 Andrea아닌 경우에만 어떻게해야합니까?


편집 : 이 정규식을 사용하는 프로그램을 작성할 것입니다 .python 또는 php에서 정규식을 배우기 위해 먼저이 일을하고 있습니다. :) 다른 유형 의 줄이 있습니다. 정규식을 사용하고 싶었습니다. 관심있는 유형을 선택합니다.이 라인을 확보 한 후에는 알려진 값과 일치하지 않도록 다른 필터를 적용해야합니다. 다른 모든 필터가 필요합니다. (?! 원하지 않음)이 꽤 잘 작동합니다. 감사합니다. :-)

나는 이것이 질문을 명확히하기를 바랍니다. :)


실제로 수행중인 작업에 대해 더 많은 정보를 제공하고 누군가가 대체 솔루션을 제공 할 수 있는지 확인하는 것이 더 나을 것 같습니다. 일반적으로 각 줄과 일치하는 정규식을 구성하여 전체 파일을 구문 분석하는 것은 다소 복잡한 경로입니다. :)
Dan

답변:


70
(?!Andrea).{6}

정규식 엔진이 부정적인 예측을 지원한다고 가정합니다.

편집 : .. 또는 [A-Za-z]{6}대신 사용하고 싶을 수도 있습니다..{6}

편집 (다시) : 예견과 예후는 일반적으로 정규식 일치를 "반전"하는 올바른 방법이 아닙니다. 정규 표현식은 실제로 네거티브 매칭을 수행하도록 설정되어 있지 않으며 사용하는 언어에 관계없이 그대로 둡니다.


@Vinko Vrsalovic이 사용하는 ^를 추가하여 "ndrea \ n"에서 일치하지 않도록해야합니다.
bdukes

2
. 기본적으로 \ n 일치하지 않습니다 (일부 언어 [예 : Perl]에서는 해당 동작을 켤 수 있지만 기본적으로. 모든 항목과 일치하지만 \ n).
Dan

1
(또한 OP는 줄의 시작 부분에 문자열이 있어야한다고 언급 한 적이 없습니다.)
Dan

1
OP에 대해 무엇을 의미합니까?
Andrea Ambu

1
Andrea : OP는 "원본 포스터"를 의미하므로 여러분을 언급했습니다. :)
Dan

47

Python / Java의 경우

^(.(?!(some text)))*$

http://www.lisnichenko.com/articles/javapython-inverse-regex.html


4
이것은 작동하지 않습니다. Tempered Greedy Token 관용구를 생각하고 계십니다. 그러나 점은 가야 하지 이전과 내다. 이 질문을 참조하십시오 . 그러나 그 접근 방식은 어쨌든이 작업에 과잉입니다.
앨런 무어

어떤 언어로 작성되었는지는 모르지만 Sublime 텍스트의 매력처럼 작동하여 테스트 데이터를 정리했습니다. 감사!
Matthias dirickx

1
@AlanMoore 실제로이 사용 사례에서는 거의 작동합니다. 그러나 some text줄을 시작하면 잘못된 결과를 반환합니다.
Zenexer

2
@Zenexer, 그게 내가 의미하는 바입니다. 점이 이전이 아니라 예견 뒤에 있으면 완벽하게 작동합니다.
Alan Moore

여기에 더 많은 것을 설명 하는 링크 가 있습니다. 나는 이유를 이해하지 않습니다 ?!뿐 아니라 !.
Timo

21

Alan Moore의 피드백으로 업데이트 됨

PCRE 및 유사한 변형에서 실제로 값을 포함하지 않는 모든 행과 일치하는 정규식을 만들 수 있습니다.

^(?:(?!Andrea).)*$

이를 강화 된 탐욕스러운 토큰 이라고합니다 . 단점은 성능이 좋지 않다는 것입니다.


1
이것은 긴 형태의 Tempered Greedy Token입니다. [\s\S]두 번째 예측 뒤에 점 (또는 JavaScript에서만 유용함)을 넣으면 첫 번째 예측은 필요하지 않습니다 ^(?:(?!Andrea).)*$.
Alan Moore

@AlanMoore 좋네요! 그런 식으로 작동하는 확립 된 패턴을 찾을 수 없어서 나만의 패턴을 생각해 냈습니다. 내가 당신의 대답을 받아들이는 대신 당신은 그것을 당신의 것으로 제공해야합니다.
Zenexer

괜찮습니다. 이미 좋은 답변이 많이 있습니다. 그리고 당신은 스스로 관용구를 발명 한 것에 대한 공로를 인정받을 자격이 있습니다. 건배!
앨런 무어

왜 사용을 제안 [\S\s]합니까? OP는 "Andrea"단어를 포함하지 않고 일치하는 줄에 대해 이야기합니다. 전체 문자열에이 단어가 포함되어 있는지 확인하는 것이 아닙니다. 내가 뭔가를 놓치고 있습니까?
x-yuri

@ x-yuri 나는 당신이 옳다고 생각합니다. 나는 아마도 불일치를 무시하고 처음이 페이지를 방문한 질문에 대답했을 것입니다. 내 연결은 지금 답을 업데이트하는 것만으로는 충분하지 좋다 (<10 kbps의) 생각
Zenexer

11

어떤 언어를 사용하고 있습니까? 정규식 구현의 기능과 구문이이를 위해 중요합니다.

미리보기를 사용할 수 있습니다. 예제로 파이썬 사용

import re

not_andrea = re.compile('(?!Andrea)\w{6}', re.IGNORECASE)

그것을 분해하려면 :

(?! Andrea) 는 '다음 6 개의 문자가 "Andrea"가 아닌 경우 일치'를 의미합니다. 그렇다면

\ w 는 "단어 문자"-영숫자 문자를 의미합니다. 이것은 [a-zA-Z0-9_] 클래스와 동일합니다.

\ w {6} 는 정확히 6 개의 단어 문자를 의미합니다.

re.IGNORECASE 는 "Andrea", "andrea", "ANDREA"를 제외한다는 의미입니다. ...

또 다른 방법은 프로그램 논리를 사용하는 것입니다. Andrea와 일치하지 않는 모든 줄을 사용하고 두 번째 정규식을 통해 6자를 확인합니다. 또는 먼저 최소 6 개의 단어 문자를 확인한 다음 Andrea와 일치하지 않는지 확인하십시오.


7

부정적인 예견 주장

(?!Andrea)

이것은 정확히 반전 된 일치는 아니지만 정규식으로 직접 수행 할 수있는 최선의 방법입니다. 하지만 모든 플랫폼이이를 지원하는 것은 아닙니다.


1
질문자가 설명 할 때까지 경기가 줄의 시작 부분에서 시작되어야한다는 것을 알지 못합니다. 그래서 왜 ^?
Hamish Downer

내가 이해 때문에 그는 줄의 시작, 편집 주어진 해명에 확인하고 싶어서
Vinko Vrsalovic

5

RegexBuddy에서이 작업을 수행하려면 정규식과 일치하지 않는 모든 행의 목록을 가져 오는 두 가지 방법이 있습니다.

테스트 패널의 도구 모음에서 테스트 범위를 "줄 단위"로 설정합니다. 이렇게하면 같은 도구 모음의 모두 나열 단추 아래에 일치하지 않는 모든 줄 나열 항목이 나타납니다. (모두 나열 단추가 보이지 않으면 주 도구 모음에서 일치 단추를 클릭하십시오.)

GREP 패널에서 "line-based"및 "invert results"확인란을 설정하여 검색중인 파일에서 일치하지 않는 라인 목록을 가져올 수 있습니다.


5

(?!실제로 유용합니다. 엄밀히 말하면 앞을 내다 보는 것은 수학적으로 정의 된 정규식이 아닙니다.

반전 정규식을 수동으로 작성할 수 있습니다.

다음은 결과를 자동으로 계산 하는 프로그램 입니다. 그 결과는 기계에서 생성되며 일반적으로 손으로 쓰는 것보다 훨씬 더 복잡합니다. 그러나 결과는 작동합니다.


1

하드웨어 집약적 일 수 있지만 작동하는이 방법을 방금 생각해 냈습니다.

정규식과 일치하는 모든 문자를 빈 문자열로 바꿀 수 있습니다.

이것은 oneliner입니다.

notMatched = re.sub(regex, "", string)

나는 매우 복잡한 정규식을 사용해야했고 합리적인 시간 내에 모든 부분을 반전시키는 방법을 알 수 없었기 때문에 이것을 사용했습니다.

일치하는 개체가 아닌 문자열 결과 만 반환합니다!


-3

Perl에서는 할 수 있습니다

process ($ line) if ($ line = ~! / Andrea /);


4
그 구문은 잘못되었습니다. ! 나는 당신의 평균 과정 ($ 라인)의 경우 $ 라인 ~ / 안드레아 / 생각
dland
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.