developer tip

정규식에서 특정 단어를 부정하는 방법은 무엇입니까?

copycodes 2020. 10. 3. 10:57
반응형

정규식에서 특정 단어를 부정하는 방법은 무엇입니까?


에서와 같이 문자 그룹을 부정 할 수 있다는 것을 알고 [^bar]있지만 부정이 특정 단어에 적용되는 정규식이 필요합니다. 내 예제에서 어떻게 실제 "bar"부정을 부정 "any chars in bar"합니까?


이를 수행하는 가장 좋은 방법은 부정적인 예측 을 사용하는 것입니다 .

^(?!.*bar).*$

부정적 미리보기 구조는 한 쌍의 괄호로, 여는 괄호 뒤에 물음표와 느낌표가 있습니다. 미리보기 내부 [정규식 패턴].


성능이 가장 중요하지 않은 경우 두 번째 패스를 통해 결과를 실행하고 부정하려는 단어와 일치하는 결과를 건너 뛰는 것이 더 쉽습니다.

정규식은 일반적으로 스크립팅이나 성능이 낮은 작업을 수행하고 있음을 의미하므로 읽기 쉽고 이해하기 쉽고 유지 관리하기 쉬운 솔루션을 찾으십시오.


다음 정규식은 원하는 것을 수행하여 (부정적인 룩 비하인드 및 룩어 헤드가 지원되는 한) 올바르게 일치시킵니다. 유일한 문제는 개별 문자와 일치한다는 것입니다 (즉, 각 일치는 두 개의 연속 "막대"사이의 모든 문자가 아니라 단일 문자 임). 매우 긴 문자열로 작업하는 경우 높은 오버 헤드가 발생할 가능성이 있습니다.

b(?!ar)|(?<!b)a|a(?!r)|(?<!ba)r|[^bar]

네거티브 미리보기 또는 뒤보기 를 사용할 수 있습니다 .

^(?!.*?bar).*
^(.(?<!bar))*?$

또는 기본 사항 만 사용하십시오.

^(?:[^b]+|b(?:$|[^a]|a(?:$|[^r])))*$

이것들은 모두를 포함하지 않는 모든 것과 일치합니다 bar.


다음 영어 문장에 대한 정규식을 식별하는 동안이 포럼 스레드를 발견했습니다.

입력 문자열이 주어지면 이 입력 문자열이 정확히 'bar'가 아니면 모든 항목과 일치합니다 . 예를 들어 나는 'foo'뿐만 아니라 'barrier'와 'disbar'를 일치시키고 싶습니다.

여기 내가 생각해 낸 정규식이 있습니다.

^(bar.+|(?!bar).*)$

정규식에 대한 내 영어 번역은 " 'bar'로 시작하고 적어도 하나의 다른 문자가 있거나 문자열이 'bar'로 시작하지 않는 경우 문자열과 일치합니다.


해결책:

^(?!.*STRING1|.*STRING2|.*STRING3).*$

xxxxxx 확인

xxxSTRING1xxx KO (원하는 지 여부)

xxxSTRING2xxx KO (원하는 지 여부)

xxxSTRING3xxx KO (원하는 지 여부)


받아 들여지는 대답은 좋지만 정규식에 간단한 하위 표현 부정 연산자가 부족한 경우 실제로 해결 방법입니다. 이것이 grep --invert-match나가는 이유 입니다. 따라서 * nixes에서는 파이프와 두 번째 정규식을 사용하여 원하는 결과를 얻을 수 있습니다.

grep 'something I want' | grep --invert-match 'but not these ones'

여전히 해결 방법이지만 기억하기가 더 쉬울 수 있습니다.


나는 받아 들인 답변을 보완하고 늦은 답변으로 토론에 기여하고 싶습니다.

@ChrisVanOpstal 정규식 학습 을위한 훌륭한 리소스 인 이 정규식 자습서공유 했습니다 .

그러나 읽는 데 정말 많은 시간이 걸렸습니다.

니모닉 편의를 위해 치트 시트를 만들었습니다.

이 참조는 중괄호를 기반으로 [], ()그리고 {}각 클래스를 선도, 나는 리콜 쉽게 찾을.

Regex = {
 'single_character': ['[]', '.', {'negate':'^'}],
 'capturing_group' : ['()', '|', '\\', 'backreferences and named group'],
 'repetition'      : ['{}', '*', '+', '?', 'greedy v.s. lazy'],
 'anchor'          : ['^', '\b', '$'],
 'non_printable'   : ['\n', '\t', '\r', '\f', '\v'],
 'shorthand'       : ['\d', '\w', '\s'],
 }

Just thought of something else that could be done. It's very different from my first answer, as it doesn't use regular expressions, so I decided to make a second answer post.

Use your language of choice's split() method equivalent on the string with the word to negate as the argument for what to split on. An example using Python:

>>> text = 'barbarasdbarbar 1234egb ar bar32 sdfbaraadf'
>>> text.split('bar')
['', '', 'asd', '', ' 1234egb ar ', '32 sdf', 'aadf']

The nice thing about doing it this way, in Python at least (I don't remember if the functionality would be the same in, say, Visual Basic or Java), is that it lets you know indirectly when "bar" was repeated in the string due to the fact that the empty strings between "bar"s are included in the list of results (though the empty string at the beginning is due to there being a "bar" at the beginning of the string). If you don't want that, you can simply remove the empty strings from the list.


I had a list of file names, and I wanted to exclude certain ones, with this sort of behavior (Ruby):

files = [
  'mydir/states.rb',      # don't match these
  'countries.rb',
  'mydir/states_bkp.rb',  # match these
  'mydir/city_states.rb' 
]
excluded = ['states', 'countries']

# set my_rgx here

result = WankyAPI.filter(files, my_rgx)  # I didn't write WankyAPI...
assert result == ['mydir/city_states.rb', 'mydir/states_bkp.rb']

Here's my solution:

excluded_rgx = excluded.map{|e| e+'\.'}.join('|')
my_rgx = /(^|\/)((?!#{excluded_rgx})[^\.\/]*)\.rb$/

My assumptions for this application:

  • The string to be excluded is at the beginning of the input, or immediately following a slash.
  • The permitted strings end with .rb.
  • Permitted filenames don't have a . character before the .rb.

Extracted from this comment by bkDJ:

^(?!bar$).*

The nice property of this solution is that it's possible to clearly negate (exclude) multiple words:

^(?!bar$|foo$|banana$).*

참고URL : https://stackoverflow.com/questions/1240275/how-to-negate-specific-word-in-regex

반응형