정규식-특정 패턴을 제외한 모든 것을 일치시키는 방법


171

특정 패턴을 충족하지 않는 문자열과 일치하도록 정규식을 작성하는 방법은 무엇입니까? 나는 (A와 ~ B) 패턴과 일치 해야하는 상황에 직면 해 있습니다.


PCRE가 가장 적합합니다. 정규식 일치 패턴을 참조하십시오 . findstr여기에있는 모든 답변이 태그에 유효하지 않기 때문에 태그를 제거했습니다 .
Wiktor Stribiżew

답변:


192

미리보기 어설 션을 사용할 수 있습니다.

(?!999)\d{3}

이 예는 이외의 세 자리 숫자와 일치 999합니다.


그러나이 기능을 사용하여 정규식 구현을하지 않는 경우 ( 정규식 플레이버 비교 참조 ) 자체적으로 기본 기능을 사용하여 정규식을 작성해야합니다.

기본 구문 만있는 호환 가능한 정규식은 다음과 같습니다.

[0-8]\d\d|\d[0-8]\d|\d\d[0-8]

이것도 아닌 세 자리 시퀀스와 일치합니다 999.


1
Look-ahead는 표준 정규 표현식 구문이 아니며 Perl 확장이며 Perl, PCRE (Perl-Compatible RegEx) 또는 기타 비표준 구현에서만 작동합니다.
Juliano

10
표준이 아니지만 대부분의 현대 언어가 지원하지 않습니까? 요즘 미리보기를 지원 하지 않는 언어 무엇입니까 ?
Bryan Oakley

1
사실입니다. 그러나 대부분의 정규 표현식은이 기능을 지원합니다 (< regular-expressions.info/refflavors.html> 참조 ).
Gumbo

1
내가 마지막 정규식도 009, 019 ... 등 일치하지 않을 생각
세바스찬 Viereck

1
C 표준 렉스 PCREs :-( 사용하지 않습니다
pieman72

30

문자열에서 단어 A를 일치시키고 단어 B를 일치시키지 않으려는 경우 예를 들면 다음과 같습니다. 텍스트가있는 경우 :

1. I have a two pets - dog and a cat
2. I have a pet - dog

당신은 텍스트 행을 검색하려면 개를 가질 애완 동물과 고양이가없는 이 정규 표현식을 사용할 수 있습니다 :

^(?=.*?\bdog\b)((?!cat).)*$

두 번째 줄만 찾습니다.

2. I have a pet - dog

그는 질문에서 언급하지 못했지만 OP는 실제로 DOS findstr명령을 사용하고 있습니다. 정규식 도구에서 찾을 수있는 기능 중 일부만 제공합니다. lookahead는 그들 사이에 없습니다. (방금 findstr 태그를 직접 추가했습니다 .)
Alan Moore

2
흠, 그래, 나는 지금 게시물에 대한 그의 의견 중 하나에서 발견했다. 제목에서 Regex를 보았습니다. 누군가가이 게시물을 발견하면 내가 그랬던 것처럼 어쨌든, 어쩌면 의견을 주셔서 감사합니다 :) 누군가에게 도움이 될 수있는, 정규 표현식에 대해 동일한 검색 할 때
하기 Aleks

15

패턴과 일치하고 호스트 언어를 사용하여 일치의 부울 결과를 반전시킵니다. 이것은 훨씬 더 읽기 쉽고 유지 보수가 쉬울 것입니다.


1
그런 다음 (A 및 ~ B) 대신 (~ A 또는 B)로 끝납니다. 내 문제를 해결하지 못합니다.
not not

1
의사 코드 : String toTest; if (toTest.matches (A) AND! toTest.matches (B)) {...}
Ben S

나는 더 분명 했어야했다 – 조각들은 완전히 독립적이지 않다. A가 문자열의 일부와 일치하면 ~ B가 나머지 부분과 일치하는지 걱정할 필요가 있습니다. 이것은 Windows 명령 줄 findstr 함수를위한 것이 었습니다.이 함수는 진정한 정규식으로 제한되어 있기 때문에 문제가 있습니다.
not not

8

언급되지 않은 간단한 해결책이 있었기 때문에이 고대의 질문을 부활시키는 것은 아닙니다. ( 정규 현상금 퀘스트를 조사하는 동안 질문을 찾았습니다 .)

나는 (A와 ~ B) 패턴과 일치 해야하는 상황에 직면 해 있습니다.

이를위한 기본 정규식은 매우 간단합니다. B|(A)

전체 경기를 무시하고 A가 포함될 그룹 1 캡처를 조사하십시오.

예 (정규식에서 html 파싱에 대한 모든 면책 조항 포함) : A는 숫자, B는 안의 숫자 <a tag

정규식 : <a.*?<\/a>|(\d+)

데모 (오른쪽 아래 창에서 그룹 1을보십시오)

참고

상황 s1, s2, s3을 제외하고 패턴을 일치시키는 방법

다음과 같은 경우를 제외하고 패턴을 일치시키는 방법 ...


사실이 아닌 것 같네요! 불행하게도,이 솔루션은 보편적하지 않고 심지어 교체 한 후, 이맥스 실패 \d와 함께 [[:digit:]]. 첫 번째 참고 문헌 은 Perl과 PHP에만 해당한다고 언급합니다. "Perl과 PHP에 고유 한 구문을 사용하는 변형이 있습니다."
miguelmorin

4

정규 언어의 보완은 정규 언어이지만이를 구성 하려면 정규 언어에 대한 DFA 를 작성하고 유효한 상태를 오류로 변경해야합니다. 예를 보려면 이것을 참조하십시오 . 어떤 페이지가 말을하지 않는 것은 변환이다 /(ac|bd)//(a[^c]?|b[^d]?|[^ab])/. DFA에서 정규 표현식으로 다시 변환하는 것은 쉽지 않습니다. 이전에 제안한 것처럼 정규식을 변경하지 않고 코드의 의미를 변경할 수 있으면 더 쉽습니다.


2
실제 정규 표현식을 다루는 경우 모두 무시할 수 있습니다. 정규 표현식은 이제 대부분의 언어가 지원하는 패턴 일치의 CSG-ish (?) 공간을 참조하는 것으로 보입니다. (A와 ~ B)를 일치시켜야하기 때문에 부정을 제거하고 한 번에 모든 것을 할 수있는 방법이 없습니다.
not not

findstr이 위에서 설명한 것처럼 findstr이 실제 DFA 정규 표현식 이외의 작업을 수행 한 경우이를 수행했을 것입니다. 모든 것은 이상한 일이며 왜이 명령 줄 (지금 배치) 스타일을 수행 해야하는지 모르겠습니다. 내 손이 묶여있는 또 하나의 예일뿐입니다.
not not

1
@ notnot : Windows에서 findstr을 사용하고 있습니까? 그런 다음 / v 만 있으면됩니다. : findstr 입력 파일 | findstr / v B> outputfile.txt 첫 번째는 모든 행을 A와 일치시키고, 두 번째는 B가없는 모든 행과 일치합니다.
Juliano

감사! 그것은 실제로 내가 필요한 것입니다. 그래도 그런 식으로 질문하지 않았으므로 더 일반적인 답변을 위해 Gumbo에 대한 답변을 계속 제공합니다.
not not

1

패턴-다시

str.split(/re/g) 

패턴을 제외한 모든 것을 반환합니다.

여기서 테스트


아마도 다시 가입해야한다고 언급하고 싶을 것입니다.
tomdemuyt

비슷한 방법 replace str.replace(/re/g, '')으로을 사용하고 있으므로 다시 가입 할 필요가 없습니다. 또한 당신이 좋은 후행 \ s에 던져? str.replace(/\re\s?/g, '')다음 과 같이 당신은 문자열의 중간에 대체되는 무언가로부터 당신이 가진 중복 공간을 제거합니다
jakecraige

0

내 대답은 여기에서도 문제를 해결할 수 있습니다.

https://stackoverflow.com/a/27967674/543814

  • 바꾸기 대신 일치를 사용합니다.
  • 그룹 대신에 그룹 $1을 읽을 것 $2입니다.
  • 그룹 $2은 캡쳐하지 않고 만들어 졌으므로 피할 수 있습니다.

예:

Regex.Match("50% of 50% is 25%", "(\d+\%)|(.+?)");

첫 번째 캡처 그룹은 피할 패턴을 지정합니다. 마지막 캡처 그룹은 다른 모든 것을 캡처합니다. 간단히 그 그룹을 읽으십시오 $2.


0
(B)|(A)

그런 다음 그룹 2가 캡처 한 것을 사용하십시오.


그는 B가 아닌 점령 해야하며 , 모든 B 패턴을 무시하는 것이 아닙니다.
hexicle
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.