문제

나는 그것이 가능한 단어와 일치하고 그 반대의 경기를 사용하여 다른 도구(예: grep -v).그러나,그것은 가능한 일치하는 라인을 포함하지 않는 특정 단어,예를 들어, hede, 정규 표현식을 사용하여?

입력:

hoho
hihi
haha
hede

코드:

grep "<Regex for 'doesn't contain hede'>" input

원하는 출력:

hoho
hihi
haha
도움이 되었습니까?

해결책

Regex가 역 매칭을 지원하지 않는다는 개념은 전적으로 사실이 아닙니다. 부정적인 외관을 사용 하여이 동작을 모방 할 수 있습니다.

^((?!hede).)*$

위의 정규식은 모든 문자열 또는 라인이 나오지 않고 라인과 일치합니다. ~ 아니다 (서브) 문자열 'hede'를 포함합니다. 언급했듯이, 이것은 성과상이 "좋은"(또는해야 할 것”이지만 여전히, 그것은 여전히, 그것은 여전히 ~이다 가능한.

라인 브레이크 숯을 일치시켜야하는 경우 도트 알 수정 자 (후행 s 다음 패턴으로) :

/^((?!hede).)*$/s

또는 인라인 사용 :

/(?s)^((?!hede).)*$/

(여기서 /.../ 패턴의 일부가 아니라 Regex Delimiters입니다.

Dot-All Modifier를 사용할 수없는 경우 캐릭터 클래스와 동일한 동작을 모방 할 수 있습니다. [\s\S]:

/^((?!hede)[\s\S])*$/

설명

문자열은 단지 목록 일뿐입니다 n 캐릭터. 각 캐릭터 전과 각 캐릭터 후에는 빈 문자열이 있습니다. 그래서 목록 n 캐릭터는 가질 것입니다 n+1 빈 줄. 문자열을 고려하십시오 "ABhedeCD":

    ┌──┬───┬──┬───┬──┬───┬──┬───┬──┬───┬──┬───┬──┬───┬──┬───┬──┐
S = │e1│ A │e2│ B │e3│ h │e4│ e │e5│ d │e6│ e │e7│ C │e8│ D │e9│
    └──┴───┴──┴───┴──┴───┴──┴───┴──┴───┴──┴───┴──┴───┴──┴───┴──┘

index    0      1      2      3      4      5      6      7

어디에 e빈 줄입니다. 성과선 (?!hede). 서브 스트링이 없는지 확인합니다 "hede" 볼 수 있도록 . (DOT)는 라인 브레이크를 제외한 모든 문자와 일치합니다. 외관도 호출됩니다 제로 폭의 assertions 그들은하지 않기 때문에 소비하다 모든 캐릭터. 그들은 단지 무언가를 주장/검증합니다.

따라서 내 예에서는 모든 빈 문자열이 먼저 검증되어 "hede" 앞으로, 캐릭터가 . (점). 성과선 (?!hede). 한 번만 그렇게하므로 그룹으로 싸서 0 이상을 반복했습니다. ((?!hede).)*. 마지막으로, 시작 및 입력 종료는 전체 입력이 소비되도록 고정되어 있습니다. ^((?!hede).)*$

보시다시피, 입력 "ABhedeCD" 켜져 있기 때문에 실패합니다 e3, 성과 (?!hede) 실패합니다 (거기 ~이다 "hede" 앞서!).

다른 팁

해결책에 주목하십시오 하지 않습니다 시작합니다 "hede":

^(?!hede).*$

일반적으로 솔루션보다 훨씬 효율적입니다 하지 않습니다 포함하다 "hede":

^((?!hede).)*$

전자는 모든 위치가 아닌 입력 문자열의 첫 번째 위치에서만 "hede"를 확인합니다.

만약에 당신은 단지 grep에 그것을 사용하고 있습니다. 당신은 사용할 수 있습니다. grep -v hede Hede가 포함되지 않은 모든 라인을 얻으려면.

에타 오, 질문을 다시 읽고 grep -v 아마도 당신이 "도구 옵션"의 의미 일 것입니다.

대답:

^((?!hede).)*$

설명:

^문자열의 시작,( 그룹 및 캡처 1 (0 번 이상 (가능한 가장 많은 금액과 일치)),),
(?! 미리 살펴보십시오.

hede 당신의 줄,

) 외모의 끝,. n을 제외한 모든 캐릭터
)* 1의 끝 (참고 :이 캡처에서 Quantifier를 사용하고 있기 때문에 캡처 된 패턴의 마지막 반복 만 1에 저장됩니다).
$ 옵션 n 전과 문자열 끝.

주어진 답변은 완벽하게 괜찮습니다. 학문적 요점은 다음과 같습니다.

이론적 컴퓨터 과학의 의미에서 정기적 인 표현 할 수 없습니다 이렇게하십시오. 그들에게는 다음과 같이보아야했습니다.

^([^h].*$)|(h([^e].*$|$))|(he([^h].*$|$))|(heh([^e].*$|$))|(hehe.+$) 

이것은 전체 일치 만합니다. 하위 경기를 위해 그것을하는 것은 더 어색 할 것입니다.

REGEX 테스트를 원한다면 실패하면 전체 문자열 일치, 다음은 작동합니다.

^(?!hede$).*

예를 들어 - "foo"(예 : "foofoo", "barfoo"및 "foobar"를 제외한 모든 값을 허용하려면 다음을 사용합니다. ^(?!foo$).*

물론, 당신이 확인하는 경우 정확한 평등,이 경우 더 나은 일반적인 솔루션은 문자열 평등을 확인하는 것입니다.

myStr !== 'foo'

당신은 부정을 넣을 수도 있습니다 밖의 Regex 기능이 필요한 경우 테스트 (여기, 케이스 무감각 및 범위 일치) :

!/^[a-f]oo$/i.test(myStr)

그러나이 답변의 맨 위에있는 Regex 솔루션은 긍정적 인 Regex 테스트가 필요한 상황 (아마도 API)에서 도움이 될 수 있습니다.

FWIW는 일반 언어 (일명 합리적 언어)가 보완하에 닫히기 때문에 다른 표현을 무효화하는 정규 표현 (일명 합리적 표현)을 찾을 수 있습니다. 그러나 많은 도구가 이것을 구현하지는 않습니다.

VCSN 이 연산자를 지원합니다 (이것은 그것을 나타냅니다 {c}, postfix).

먼저 표현의 유형을 정의합니다. 레이블은 문자입니다.lal_char) 선택합니다 a 에게 z 예를 들어 (보완 작업을 할 때 알파벳을 정의하는 것은 물론 매우 중요합니다), 각 단어에 대해 계산 된 "값"은 단지 부울입니다. true 단어가 받아 들여지고 false, 거부.

파이썬에서 :

In [5]: import vcsn
        c = vcsn.context('lal_char(a-z), b')
        c
Out[5]: {a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z} → 𝔹

그런 다음 표현을 입력합니다.

In [6]: e = c.expression('(hede){c}'); e
Out[6]: (hede)^c

이 표현식을 오토마톤으로 변환하십시오.

In [7]: a = e.automaton(); a

The corresponding automaton

마지막 으로이 오토 마톤을 간단한 표현으로 다시 변환하십시오.

In [8]: print(a.expression())
        \e+h(\e+e(\e+d))+([^h]+h([^e]+e([^d]+d([^e]+e[^]))))[^]*

어디 + 일반적으로 표시됩니다 |, \e 빈 단어를 나타냅니다 [^] 일반적으로 작성됩니다 . (모든 캐릭터). 그래서 약간의 재 작성과 함께 ()|h(ed?)?|([^h]|h([^e]|e([^d]|d([^e]|e.)))).*.

이 예를 볼 수 있습니다 여기, VCSN을 온라인으로 시도하십시오 거기.

여기에 있습니다 좋은 설명 임의의 반대를 부정하는 것이 쉽지 않은 이유. 그래도 다른 답변에 동의해야합니다. 이것이 가상의 질문 이외의 다른 것이라면, 정규식은 여기에서 올바른 선택이 아닙니다.

부정적인 전망대를 사용하면 정규 표현식에는 특정 패턴이 포함되지 않은 것이 일치 할 수 있습니다. 이것은 Bart Kiers가 답변하고 설명합니다. 훌륭한 설명!

그러나 Bart Kiers의 답변을 사용하면 LookaheAd 부분은 단일 캐릭터와 일치하는 동안 1 ~ 4 자 앞에 테스트합니다. 우리는 이것을 피할 수 있고,보기 부분에서 전체 텍스트를 확인하고, 'hede'가 없는지 확인한 다음 정상 부분 (.*)은 한 번에 전체 텍스트를 모두 먹을 수 있습니다.

개선 된 Regex는 다음과 같습니다.

/^(?!.*?hede).*$/

부정적인보기 부분의 (*?) Lazy Quantifier는 선택 사항입니다. (*) Greedy Quantifier 대신 데이터에 따라 사용할 수 있습니다. 더 빨리; 그렇지 않으면 탐욕스러운 정량자가 더 빨라집니다. 그러나 'hede'가 존재하지 않으면 둘 다 동일하게 느립니다.

여기에 있습니다 데모 코드.

Lookahead에 대한 자세한 내용은 위대한 기사를 확인하십시오. 마스터 잉어와 외모.

또한 체크 아웃하십시오 regexgen.js, 복잡한 정규 표현식을 구성하는 데 도움이되는 JavaScript 정규식 발전기. regexgen.js를 사용하면 Regex를보다 읽기 쉬운 방식으로 구성 할 수 있습니다.

var _ = regexGen;

var regex = _(
    _.startOfLine(),             
    _.anything().notContains(       // match anything that not contains:
        _.anything().lazy(), 'hede' //   zero or more chars that followed by 'hede',
                                    //   i.e., anything contains 'hede'
    ), 
    _.endOfLine()
);

벤치 마크

제시된 옵션 중 일부를 평가하고 성능을 비교하고 새로운 기능을 사용하기로 결정했습니다. .NET Regex 엔진의 벤치마킹 : http://regexhero.net/tester/

벤치 마크 텍스트 :

검색 된 표현식이 포함되어 있기 때문에 처음 7 줄은 일치하지 않아야하며, 낮은 7 줄은 일치해야합니다!

Regex Hero is a real-time online Silverlight Regular Expression Tester.
XRegex Hero is a real-time online Silverlight Regular Expression Tester.
Regex HeroRegex HeroRegex HeroRegex HeroRegex Hero is a real-time online Silverlight Regular Expression Tester.
Regex Her Regex Her Regex Her Regex Her Regex Her Regex Her Regex Hero is a real-time online Silverlight Regular Expression Tester.
Regex Her is a real-time online Silverlight Regular Expression Tester.Regex Hero
egex Hero egex Hero egex Hero egex Hero egex Hero egex Hero Regex Hero is a real-time online Silverlight Regular Expression Tester.
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRegex Hero is a real-time online Silverlight Regular Expression Tester.

Regex Her
egex Hero
egex Hero is a real-time online Silverlight Regular Expression Tester.
Regex Her is a real-time online Silverlight Regular Expression Tester.
Regex Her Regex Her Regex Her Regex Her Regex Her Regex Her is a real-time online Silverlight Regular Expression Tester.
Nobody is a real-time online Silverlight Regular Expression Tester.
Regex Her o egex Hero Regex  Hero Reg ex Hero is a real-time online Silverlight Regular Expression Tester.

결과:

3의 중앙값이 실행되면서 결과는 초당 반복입니다. 더 큰 수 = 더 좋습니다

01: ^((?!Regex Hero).)*$                    3.914   // Accepted Answer
02: ^(?:(?!Regex Hero).)*$                  5.034   // With Non-Capturing group
03: ^(?>[^R]+|R(?!egex Hero))*$             6.137   // Lookahead only on the right first letter
04: ^(?>(?:.*?Regex Hero)?)^.*$             7.426   // Match the word and check if you're still at linestart
05: ^(?(?=.*?Regex Hero)(?#fail)|.*)$       7.371   // Logic Branch: Find Regex Hero? match nothing, else anything

P1: ^(?(?=.*?Regex Hero)(*FAIL)|(*ACCEPT))  ?????   // Logic Branch in Perl - Quick FAIL
P2: .*?Regex Hero(*COMMIT)(*FAIL)|(*ACCEPT) ?????   // Direct COMMIT & FAIL in Perl

.NET은 동작 동사 (*실패 등)를 지원하지 않기 때문에 솔루션 P1과 P2를 테스트 할 수 없었습니다.

요약:

나는 대부분의 제안 된 솔루션을 테스트하려고 시도했지만 특정 단어에 대해 일부 최적화가 가능합니다. 예를 들어 검색 문자열의 처음 두 글자가 동일하지 않은 경우 답변 03을 확장 할 수 있습니다.^(?>[^R]+|R+(?!egex Hero))*$ 성능이 작은 이득을 초래합니다.

그러나 가장 읽기 쉽고 성능이 뛰어난 가장 빠른 솔루션은 조건부 명세서를 사용하여 05 또는 보유량 정량기가있는 04 인 것 같습니다. PERL 솔루션이 더 빠르고 쉽게 읽을 수 있어야한다고 생각합니다.

재 조정은 아니지만, 파이프와 함께 직렬 GREP를 사용하여 노이즈를 제거하는 것이 논리적이고 유용하다는 것을 알았습니다.

예를 들어. 모든 주석이없는 Apache 구성 파일 검색-

grep -v '\#' /opt/lampp/etc/httpd.conf      # this gives all the non-comment lines

그리고

grep -v '\#' /opt/lampp/etc/httpd.conf |  grep -i dir

연쇄 grep의 논리는 (주석이 아님)이고 (DIR과 일치)

이를 통해 각 위치에서 룩보드를 테스트하지 않습니다.

/^(?:[^h]+|h++(?!ede))*+$/

(.NET)와 동일합니다.

^(?>(?:[^h]+|h+(?!ede))*)$

오래된 답변 :

/^(?>[^h]+|h+(?!ede))*$/

앞서 말한 (?:(?!hede).)* 고정 될 수 있기 때문에 훌륭합니다.

^(?:(?!hede).)*$               # A line without hede

foo(?:(?!hede).)*bar           # foo followed by bar, without hede between them

그러나이 경우에는 다음이 충분합니다.

^(?!.*hede)                    # A line without hede

이 단순화가 준비되어 있습니다. "및"Clauses는 다음과 같습니다.

^(?!.*hede)(?=.*foo)(?=.*bar)   # A line with foo and bar, but without hede
^(?!.*hede)(?=.*foo).*bar       # Same

내가하는 방법은 다음과 같습니다.

^[^h]*(h(?!ede)[^h]*)*$

다른 답변보다 정확하고 효율적입니다. 그것은 Friedl을 구현합니다 "루프를 끊임없이" 효율성 기술과 훨씬 덜 역 추적이 필요합니다.

캐릭터를 일치시키려면 문자 클래스를 부정하는 것과 유사한 단어를 부정하려면 다음과 같습니다.

예를 들어 문자열 :

<?
$str="aaa        bbb4      aaa     bbb7";
?>

사용하지 마세요:

<?
preg_match('/aaa[^bbb]+?bbb7/s', $str, $matches);
?>

사용:

<?
preg_match('/aaa(?:(?!bbb).)+?bbb7/s', $str, $matches);
?>

알아채다 "(?!bbb)." 예를 들어 보이도 외관이 아니며, 예를 들어 룩시 런트입니다.

"(?=abc)abcde", "(?!abc)abcde"

OP는 OR을 지정하지 않았습니다 꼬리표 컨텍스트 (프로그래밍 언어, 편집기, 도구)를 나타내는 게시물은 Regex가 사용됩니다.

나를 위해, 나는 때때로 사용 파일을 편집하는 동안 이것을해야합니다. Textpad.

Textpad 일부 Regex를 지원하지만 Lookahead 또는 Lookbehind를 지원하지 않으므로 몇 단계가 필요합니다.

내가 그 모든 줄을 유지하려는 경우 하지 마라 문자열을 포함합니다 hede, 나는 이것처럼 할 것이다 :

1. 전체 파일을 검색/교체하여 텍스트가 포함 된 각 줄의 시작 부분에 고유 한 "태그"를 추가하십시오.

    Search string:^(.)  
    Replace string:<@#-unique-#@>\1  
    Replace-all  

2. 문자열이 포함 된 모든 라인을 삭제합니다 hede (교체 문자열이 비어 있음) :

    Search string:<@#-unique-#@>.*hede.*\n  
    Replace string:<nothing>  
    Replace-all  

3.이 시점에서 남은 모든 선 하지 마라 문자열을 포함합니다 hede. 모든 라인에서 고유 한 "태그"를 제거합니다 (교체 문자열이 비어 있음) :

    Search string:<@#-unique-#@>
    Replace string:<nothing>  
    Replace-all  

이제 문자열이 포함 된 모든 줄이있는 원본 텍스트가 있습니다. hede 제거됨.


내가 찾고 있다면 다른 일을하십시오 그 줄만으로 하지 마라 문자열을 포함합니다 hede, 나는 이것처럼 할 것이다 :

1. 전체 파일을 검색/교체하여 텍스트가 포함 된 각 줄의 시작 부분에 고유 한 "태그"를 추가하십시오.

    Search string:^(.)  
    Replace string:<@#-unique-#@>\1  
    Replace-all  

2. 문자열이 포함 된 모든 라인에 대해 hede, 고유 한 "태그"를 제거합니다.

    Search string:<@#-unique-#@>(.*hede)
    Replace string:\1  
    Replace-all  

3.이 시점에서 고유 한 "태그"로 시작하는 모든 라인, 하지 마라 문자열을 포함합니다 hede. 나는 이제 내 할 수있다 다른 것 그 줄에만.

4. 완료되면 모든 라인에서 고유 한 "태그"를 제거합니다 (교체 문자열이 비어 있음).

    Search string:<@#-unique-#@>
    Replace string:<nothing>  
    Replace-all  

내 의견에, 상위 답변의 더 읽기 쉬운 변형 :

^(?!.*hede)

기본적으로, "라인의 시작 부분에서 일치하는 경우, 'hede'가없는 경우에만 일치하므로 요구 사항은 거의 직접적으로 번역되었습니다.

물론 여러 실패 요구 사항이있을 수 있습니다.

^(?!.*(hede|hodo|hada))

세부: ^ 앵커는 REGEX 엔진이 문자열의 모든 위치에서 일치를 다시 시도하지 않도록합니다.

^ 처음의 앵커는 선의 시작을 나타 내기위한 것입니다. GREP 도구는 여러 줄과 한 번에 하나씩 일치하며 멀티 라인 문자열로 작업하는 컨텍스트에서 "M"플래그를 사용할 수 있습니다.

/^(?!.*hede)/m # JavaScript syntax

또는

(?m)^(?!.*hede) # Inline flag

Ruby-2.4.1의 도입 이후, 우리는 새로운 것을 사용할 수 있습니다. 결석 조작자 루비의 정규 표현에서

공무원으로부터 문서

(?~abc) matches: "", "ab", "aab", "cccc", etc.
It doesn't match: "abc", "aabc", "ccccabc", etc.

따라서 귀하의 경우 ^(?~hede)$ 당신을 위해 일을합니다

2.4.1 :016 > ["hoho", "hihi", "haha", "hede"].select{|s| /^(?~hede)$/.match(s)}
 => ["hoho", "hihi", "haha"]

pcre 동사를 통해 (*SKIP)(*F)

^hede$(*SKIP)(*F)|^.*$

이것은 정확한 문자열이 포함 된 선을 완전히 건너 뜁니다. hede 남은 모든 라인과 일치합니다.

데모

부품 실행 :

두 부분으로 나누어 위의 정수를 고려해 봅시다.

  1. 앞서 | 상징. 부분 일치하지 않아야합니다.

    ^hede$(*SKIP)(*F)
    
  2. 후 부분 | 상징. 부분 일치해야합니다.

    ^.*$
    

1 부

Regex Engine은 첫 번째 부분에서 실행을 시작합니다.

^hede$(*SKIP)(*F)

설명:

  • ^ 우리가 처음에 있다고 주장합니다.
  • hede 문자열과 일치합니다 hede
  • $ 우리가 라인 끝에 있다고 주장합니다.

그래서 문자열이 포함 된 선 hede 일치합니다. Regex 엔진이 다음을 볼 수 있습니다 (*SKIP)(*F) (참고 : 글을 쓸 수 있습니다 (*F) ~처럼 (*FAIL)) 동사, 그것은 건너 뛰고 일치를 실패합니다. | PCRE 동사 옆에 추가 된 Alteration 또는 Logical 또는 연산자라고 불리는 것은 선에 정확한 문자열이 포함 된 모든 라인의 모든 문자 사이에 존재하는 모든 경계가 일치하는 PCRE 동사 옆에 추가됩니다. hede. 데모를 참조하십시오 여기. 즉, 나머지 문자열의 문자와 일치하려고합니다. 이제 두 번째 부분의 정규식이 실행됩니다.

2 부

^.*$

설명:

  • ^ 우리가 처음에 있다고 주장합니다. 즉, 그것은 모든 줄을 제외한 모든 줄을 일치시킵니다. hede 선. 데모를 참조하십시오 여기.
  • .* 멀티 린 모드에서 . Newline 또는 Carriage Return 문자를 제외한 모든 캐릭터와 일치합니다. 그리고 * 이전 문자를 0 이상 반복합니다. 그래서 .* 전체 라인과 일치합니다. 데모를 참조하십시오 여기.

    왜 당신이 추가했는지.* 대신.+?

    왜냐하면 .* 빈 줄과 일치하지만 .+ 빈과 일치하지 않습니다. 우리는 제외한 모든 줄과 일치하고 싶습니다 hede , 입력에 빈 선이있을 수 있습니다. 그래서 당신은 사용해야합니다 .* 대신에 .+ . .+ 이전 문자를 한 번 이상 반복합니다. 보다 .* 빈 줄과 일치합니다 여기.

  • $ 여기서 라인 앵커의 끝이 필요하지 않습니다.

다른 사람은 그 질문에 대한 직접적인 답을주지 않았기 때문에 그것은 물었다, 나는 그것을 할 거 야.

대답은 Posix와 함께하는 것입니다 grep,이 요청을 문자 그대로 만족시키는 것은 불가능합니다.

grep "Regex for doesn't contain hede" Input

그 이유는 그 posix입니다 grep 함께 일하기 만하면됩니다 기본 정규 표현, 이 작업은 그 작업을 수행하기에 충분히 강력하지 않습니다 (대체 및 그룹화 부족으로 인해 일반 언어를 구문 분석 할 수 없습니다).

그러나 GNU grep 그것을 허용하는 확장을 구현합니다. 특히, \| GNU의 BRES 구현에서 교대 연산자이며 \( 그리고 \) 그룹화 연산자입니다. 정규 표현식 엔진이 교대, 네거티브 브래킷 표현식, 그룹화 및 Kleene 스타를 지원하고 문자열의 시작과 끝에 고정 할 수 있다면,이 접근법에 필요한 전부입니다.

GNU와 함께 grep, 그것은 다음과 같습니다.

grep "^\([^h]\|h\(h\|eh\|edh\)*\([^eh]\|e[^dh]\|ed[^eh]\)\)*\(\|h\(h\|eh\|edh\)*\(\|e\|ed\)\)$" Input

(발견 된 큰 쟁반 그리고 손으로 이루어진 몇 가지 추가 최적화).

구현하는 도구를 사용할 수도 있습니다 확장 정규 표현, 처럼 egrep, 백 슬래시를 제거하려면 :

egrep "^([^h]|h(h|eh|edh)*([^eh]|e[^dh]|ed[^eh]))*(|h(h|eh|edh)*(|e|ed))$" Input

다음은 테스트하는 스크립트입니다 (파일을 생성합니다. testinput.txt 현재 디렉토리에서) :

#!/bin/bash
REGEX="^\([^h]\|h\(h\|eh\|edh\)*\([^eh]\|e[^dh]\|ed[^eh]\)\)*\(\|h\(h\|eh\|edh\)*\(\|e\|ed\)\)$"

# First four lines as in OP's testcase.
cat > testinput.txt <<EOF
hoho
hihi
haha
hede

h
he
ah
head
ahead
ahed
aheda
ahede
hhede
hehede
hedhede
hehehehehehedehehe
hedecidedthat
EOF
diff -s -u <(grep -v hede testinput.txt) <(grep "$REGEX" testinput.txt)

내 시스템에서 인쇄 :

Files /dev/fd/63 and /dev/fd/62 are identical

예상대로.

세부 사항에 관심이있는 사람들의 경우, 사용 된 기술은 단어와 일치하는 정규 표현을 유한 자동화로 변환 한 다음 모든 수용 상태를 비 수락으로 변경하고 그 반대를 그 반대로 바꾸어 오토 마톤을 반전시키는 것입니다. 정규 표현.

마지막으로, 모든 사람이 지적했듯이, 정규 표현 엔진이 부정적인 룩보드를 지원하면 그 작업을 많이 단순화합니다. 예를 들어 GNU Grep을 사용하여 :

grep -P '^((?!hede).)*$' Input

업데이트: 나는 최근 Kendall Hopkins의 우수한 것을 발견했습니다 형식 이론 Grail과 유사한 기능을 제공하는 PHP로 작성된 라이브러리. 이를 사용하여 직접 작성한 단순화자를 사용하여 입력 문구 (현재 지원되는 영숫자 및 공간 문자 만)가 주어진 부정적인 정규식의 온라인 생성기를 쓸 수있었습니다. http://www.formauri.es/personal/pgimeno/misc/non-match-regex/

을 위한 hede 출력 :

^([^h]|h(h|e(h|dh))*([^eh]|e([^dh]|d[^eh])))*(h(h|e(h|dh))*(ed?)?)?$

위의 것과 같습니다.

수도 유지 보수성 향상을 두 가지 정규표현식에 코드에서 하나 할 첫 번째 일치하고,다음과 일치하는 경우 실행하여 두 번째 정규 표현식을 확인에 대한 이상값 경우에 당신을 차단한 예제 ^.*(hede).* 다음 적절한 논리에서 당신의 코드입니다.

OK,나이를 인정하지 않은 정말 답하는 게시된 질문이 게시하고 또한 사용될 수 있습니다 약간 더 가공보다는 하나의 정규식으로 이루어져 있습니다.그러나 개발자를 위한 온 찾고 여기에 빠른 긴급 수정을 위한 이상값 경우 다음 이 솔루션은 간과해서는 안된다.

그만큼 TXR 언어 Regex 부정을 지원합니다.

$ txr -c '@(repeat)
@{nothede /~hede/}
@(do (put-line nothede))
@(end)'  Input

더 복잡한 예 : 시작하는 모든 라인과 일치 a 그리고 끝납니다 z, 그러나 서브 스트링을 포함하지 마십시오 hede:

$ txr -c '@(repeat)
@{nothede /a.*z&~.*hede.*/}
@(do (put-line nothede))
@(end)' -
az         <- echoed
az
abcz       <- echoed
abcz
abhederz   <- not echoed; contains hede
ahedez     <- not echoed; contains hede
ace        <- not echoed; does not end in z
ahedz      <- echoed
ahedz

REGEX 부정은 그 자체로는 특히 유용하지 않지만 교차로가있을 때는 부울 세트 작업 세트가 있기 때문에 흥미로워집니다. ""일치하는 것과 일치하는 세트 "를 표현할 수 있습니다.

아래 함수는 원하는 출력을 얻는 데 도움이됩니다.

<?PHP
      function removePrepositions($text){

            $propositions=array('/\bfor\b/i','/\bthe\b/i'); 

            if( count($propositions) > 0 ) {
                foreach($propositions as $exceptionPhrase) {
                    $text = preg_replace($exceptionPhrase, '', trim($text));

                }
            $retval = trim($text);

            }
        return $retval;
    }


?>

PCRE의 역 추적 제어 동사를 사용하여 단어가 포함되지 않은 선에 일치하는 방법

다음은 전에 본 적이없는 방법입니다.

/.*hede(*COMMIT)^|/

작동 방식

먼저, 그것은 줄 어딘가에 "hede"를 찾으려고합니다. 이 시점에서 성공하면 (*COMMIT) 고장시기에 역 추적이 아니라,이 경우 더 이상 일치하는 것을 시도하지 않도록 엔진에 엔진을 지시합니다. 그런 다음 일치 할 수없는 것을 일치 시키려고 노력합니다 (이 경우, ^).

선에 "hede"가 포함되어 있지 않으면 두 번째 대안 인 빈 하위 패턴은 주제 문자열과 성공적으로 일치합니다.

이 방법은 부정적인 전망대보다 더 효율적이지는 않지만 누군가가 멋진 것을 발견하고 다른 더 흥미로운 응용 프로그램에 사용하는 경우를 대비하여 여기에 던질 것이라고 생각했습니다.

아마도 Google에서 이것을 찾을 수있을 것입니다. ~ 아니다 서브 스트링을 포함합니다. 알아 내기 위해 잠시 너무 나중에 공유하겠습니다.

주어진 문자열 : <span class="good">bar</span><span class="bad">foo</span><span class="ugly">baz</span>

나는 일치하고 싶다 <span> "나쁜"하위 문자열을 포함하지 않는 태그.

/<span(?:(?!bad).)*?> 일치합니다 <span class=\"good\"> 그리고 <span class=\"ugly\">.

괄호의 두 세트 (레이어)가 있습니다.

  • 가장 안쪽은 부정적인 전망대를위한 것입니다 (캡처 그룹이 아닙니다)
  • 가장 바깥 쪽은 루비에 의해 캡처 그룹으로 해석되었지만 우리는 그것이 캡처 그룹이되기를 원하지 않으므로 추가? : 처음에 캡처 그룹으로 해석되지 않습니다.

루비 데모 :

s = '<span class="good">bar</span><span class="bad">foo</span><span class="ugly">baz</span>'
s.scan(/<span(?:(?!bad).)*?>/)
# => ["<span class=\"good\">", "<span class=\"ugly\">"]

더 간단한 솔루션은 NOT 연산자를 사용하는 것입니다 !

당신의 만약에 진술은 "포함 된"과 "제외"와 일치하지 않아야합니다.

var contains = /abc/;
var excludes =/hede/;

if(string.match(contains) && !(string.match(excludes))){  //proceed...

Regex의 디자이너는 NOT 운영자의 사용을 기대했다고 생각합니다.

와 함께 Conyedit, 명령 줄을 사용할 수 있습니다 cc.gl !/hede/ Regex 매칭이 포함되지 않은 줄을 얻거나 명령 줄을 사용하려면 cc.dl /hede/ Regex 매칭이 포함 된 라인을 삭제합니다. 그들은 같은 결과를 가지고 있습니다.

^((?! hede).)*$는 문자를 소비하기 때문에 다른 기준과 결합 할 수 없다는 것을 제외하고는 우아한 솔루션입니다. 예를 들어, "hede"의 비 언급과 "하하"의 존재를 확인하고 싶다고 가정 해 봅시다. 이 솔루션은 문자를 소비하지 않기 때문에 작동합니다.

^(?!.bhede b) (? =.bhaha b)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top