단어를 일치시킨 다음 다른 도구 (예 :)를 사용하여 일치를 되돌릴 수 있다는 것을 알고 있습니다 grep -v
. 그러나 hede
정규 단어 를 사용하여 특정 단어를 포함하지 않는 행을 일치시킬 수 있습니까?
입력:
hoho
hihi
haha
hede
암호:
grep "<Regex for 'doesn't contain hede'>" input
원하는 출력 :
hoho
hihi
haha
답변
정규 표현식이 역 매칭을 지원하지 않는다는 개념은 전적으로 사실이 아닙니다. 부정적인 둘러보기를 사용하여이 동작을 모방 할 수 있습니다.
^((?!hede).)*$
위의 정규 표현식 은 (하위) 문자열 ‘hede’를 포함 하지 않는 모든 문자열 또는 줄 바꿈이없는 행과 일치합니다 . 언급 한 바와 같이,이 정규식에서 “좋은”(또는해야 할) 것이 아닙니다,하지만 여전히, 그것은 이다 가능합니다.
또한 줄 바꿈 문자도 일치시켜야하는 경우 DOT-ALL 수정자를 사용하십시오 ( s
다음 패턴 의 후행 ).
/^((?!hede).)*$/s
또는 인라인으로 사용하십시오.
/(?s)^((?!hede).)*$/
(여기서 /.../
정규 표현식 구분 기호는 패턴의 일부가 아닙니다)
DOT-ALL 수정자를 사용할 수없는 경우 문자 클래스를 사용하여 동일한 동작을 모방 할 수 있습니다 [\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"
보고, 그 경우 (다른 것이 보이면) .
(점)은 줄 바꿈을 제외한 모든 문자와 일치합니다. 둘러보기는 문자를 소비 하지 않기 때문에 폭이 0 인 어설 션 이라고도 합니다 . 그들은 단지 무언가를 주장하고 / 확인한다.
따라서 내 예에서 모든 빈 문자열은 먼저 "hede"
문자가 .
(점)에 의해 소비되기 전에 선행 이 없는지 확인합니다 . 정규 표현식 (?!hede).
은 한 번만 수행하므로 그룹으로 묶여 0 회 이상 반복됩니다 ((?!hede).)*
. 마지막으로 입력 시작과 끝은 전체 입력이 소비되도록 고정됩니다.^((?!hede).)*$
당신이 볼 수 있듯이, 입력이 "ABhedeCD"
때문에 실패합니다 e3
정규식, (?!hede)
실패 (가 이다 "hede"
앞두고!).
답변
해결책 은 “hede”로 시작 하지 않습니다 .
^(?!hede).*$
“hede”를 포함 하지 않는 솔루션보다 일반적으로 훨씬 효율적입니다 .
^((?!hede).)*$
전자는 모든 위치가 아닌 입력 문자열의 첫 번째 위치에서만 “hede”를 확인합니다.
답변
경우 그냥 그렙 위해 그것을 사용하고, 당신이 사용할 수있는 grep -v hede
HEDE를 포함하지 않는 모든 라인을 얻을 수 있습니다.
ETA 오, 질문을 다시 grep -v
읽어 보면 “도구 옵션”이라는 의미 일 것입니다.
답변
대답:
^((?!hede).)*$
설명:
^
문자열의 시작,
(
그룹화 및 \ 1까지 캡처 (0 회 이상 (가장 많은 양과 일치))
(?!
없는지 확인하십시오.
hede
당신의 줄,
)
미리보기 끝,
.
\ n을 제외한 모든 문자,
)*
\ 1 끝 (참고 :이 캡처에서 수량 자를 사용하므로 캡처 된 패턴의 마지막 반복 만 \ 1에 저장 됨)
$
옵션 \ n, 그리고 문자열의 끝
답변
주어진 대답은 학문적 요점으로 완벽하게 좋습니다.
이론적 컴퓨터 과학의 의미에서 정규 표현식은 할 수없는 다음과 같이 해. 그들에게는 다음과 같이 보일 것입니다.
^([^h].*$)|(h([^e].*$|$))|(he([^h].*$|$))|(heh([^e].*$|$))|(hehe.+$)
이것은 전체 일치 만 수행합니다. 하위 경기를 위해 그것을하는 것은 더 어색 할 것입니다.
답변
전체 문자열이 일치 하는 경우 에만 정규식 테스트가 실패 하도록하려면 다음이 작동합니다.
^(?!hede$).*
예 :- “foo”를 제외한 모든 값을 허용하려면 (예 : “foofoo”, “barfoo”및 “foobar”는 통과하지만 “foo”는 실패 함) 다음을 사용하십시오. ^(?!foo$).*
물론, 당신이 정확한 동등성을 검사한다면 ,이 경우에 더 나은 일반적인 해결책은 문자열 동등성을 검사하는 것입니다.
myStr !== 'foo'
정규식 기능이 필요한 경우 테스트 외부 에서 부정을 넣을 수도 있습니다 (여기서는 대소 문자를 구분하지 않고 범위를 일치시킵니다).
!/^[a-f]oo$/i.test(myStr)
그러나이 답변의 맨 위에있는 정규식 솔루션은 긍정적 정규식 테스트가 필요한 경우 (아마도 API에 의해) 도움이 될 수 있습니다.
답변
FWIW는 정규 언어 (일명 합리적 언어)가 보완 아래 닫히므로 항상 다른 표현을 무효화하는 정규식 (일명 합리적인 표현)을 찾을 수 있습니다. 그러나이를 구현하는 도구는 많지 않습니다.
Vcsn 은이 연산자 ( {c}
후위를 나타냄 )를 지원합니다.
먼저 표현의 유형을 정의 라벨은 편지 ( 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
마지막으로,이 오토 마톤을 간단한 표현으로 다시 변환하십시오.
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.)))).*
.
