문제

약간의 regex 도움을 찾고 있습니다. 문자열과 일치하는 표현을 설계하고 싶습니다.foo" 또는 "술집", 그러나 둘 다 아닙니다"foo" 그리고 "술집"

내가 같은 일을한다면 ...

/((foo)|(bar))/

일치 할거야 "foobar". 내가 찾고있는 것이 아닙니다. 그래서, 한 용어 나 다른 용어가있을 때만 Regex 일치를 어떻게 만들 수 있습니까?

감사!

도움이 되었습니까?

해결책

당신은 단일 정규식으로 이것을 할 수 있지만, 나는 당신이 같은 일을하는 가독성을 위해 제안합니다 ...

(/foo/ and not /bar/) || (/bar/ and not /foo/)

다른 팁

이것이 제가 사용하는 것입니다.

/^(foo|bar){1}$/

보다: http://www.regular-expressions.info/quickstart.html 반복 아래

REGEX 언어가 지원하는 경우 사용하십시오 부정적인 전제:

(?<!foo|bar)(foo|bar)(?!foo|bar)

이것은 바로 앞에 있지 않거나 "foo"또는 "bar"가 뒤 따르는 "foo"또는 "bar"와 일치합니다.

일치하려는 문자열에 다른 토큰 인 "foocuzbar"가 포함될 수 있는지 질문이나 예에서 명확하지 않습니다. 그렇다면이 패턴은 작동하지 않습니다.

테스트 사례의 결과는 다음과 같습니다 ( "True"는 입력에서 패턴이 발견되었음을 의미합니다).

foo: true
bar: true
foofoo: false
barfoo: false
foobarfoo: false
barbar: false
barfoofoo: false

이것은 'foo'와 'bar'가 필요하지만 'foobar'는 아니지만 'blafoo'가 아니라 'blabar'가 아닙니다.

/^(foo|bar)$/

^ = mark start of string (or line)
$ = mark end of string (or line)

이것은 'foo'와 'bar'와 'foo bar'와 'bar-foo'가 필요하지만 'foobar'는 아니지만 'blafoo'가 아니라 'blabar'가 아닙니다.

/\b(foo|bar)\b/

\b = mark word boundry

"foo"및 "bar"이외의 내용에 관한 행동을 지정하지 않았거나 다른 하나가없는 경우 하나의 반복을 지정하지 않았습니다. 예를 들어,해야한다 "fooD "또는"바바이안 "경기?

"foo"또는 "bar"의 하나의 인스턴스 만 포함하는 문자열을 일치시키고 싶지만, 문자열의 다른 것 (예 : "음식"일치 및 일치 및 동일한 인스턴스는 모두 동일한 인스턴스가 아닙니다. "바바리안"은 일치하지 않습니다), 당신은 발견 된 경기 수를 반환하는 정규식을 사용하고 정확히 하나의 경기가 발견되는 경우에만 성공적이라고 생각할 수 있습니다. 예를 들어, Perl에서 :

@matches = ($value =~ /(foo|bar)/g)  # @matches now hold all foos or bars present
if (scalar @matches == 1) {          # exactly one match found
  ...
}

동일한 대상의 여러 반복이 허용되면 (즉, "야만인"일치), 일치 목록을 걸어 동일한 일반적인 접근 방식을 사용할 수 있습니다. 또한 존재합니다.

당신은 고려하고 싶습니까? 조건부 테스트.

(?(?=regex)then|else)

정규 표현 조건

당신이 진정한 독점을 원한다면, 나는 단지 Regex 대신 코드로 그것을 할 것입니다. Perl에서 :

/foo/ xor /bar/

하지만 귀하의 의견 :

매치 : "foo", "bar"비 일치 : "Foofoo" "Barfoo" "Foobarfoo" "Barbar" "Barfoofoo"

당신이 실제로 독점을 찾고 있지 않음을 나타냅니다. 당신은 실제로 "한다는 것을 의미합니다 /foo|bar/ 정확히 한 번 일치합니까? "

my $matches = 0;
while (/foo|bar/g) {
  last if ++$matches > 1;
}

my $ok = ($matches == 1)

나는 이것이 늦은 입장이라는 것을 알고 있지만,보고있는 다른 사람들을 돕기 위해 :

(/b(?:(?:(?!foo)bar)|(?:(?!bar)foo))/b)

나는 이런 것을 사용할 것입니다. 단어 주위의 공간을 확인하지만 사용할 수 있습니다. \b 또는 \B 사용하는 경우 테두리를 확인합니다 \w. 이것은 "foo"또는 "bar"와 일치 할 것이므로, 만일을 대비하여 공백을 교체해야 할 것입니다. (무엇이든 교체한다고 가정합니다.)

/\s((foo)|(bar))\s/

나는 이것이 단일 정규 표현으로 수행 될 수 있다고 생각하지 않습니다. 그리고 경계는 당신이 일치하는 것에 따라 작동하거나 작동하지 않을 수 있습니다.

각 Regex와 별도로 일치하고 결과에 대해 XOR을 수행합니다.

foo = re.search("foo", str) != None
bar = re.search("bar", str) != None
if foo ^ bar:
    # do someting...

나는 Regex Coach와 함께 다음과 같이 시도했습니다.

x foo y
x bar y
x foobar y

내가 확인하면 g 옵션은 실제로 세 단어가 모두 일치합니다. 각 경기 후에 다시 검색되기 때문입니다.
이 동작을 원하지 않으면 표현을 정박 할 수 있습니다 (예 : 단어 경계에서만 일치하는).

\b(foo|bar)\b

문제에 대한 더 많은 컨텍스트를 제공하면 (데이터가 어떻게 보이는지) 더 나은 답변을 줄 수 있습니다.

\b(foo)\b|\b(bar)\b

그리고 첫 번째 만 사용하십시오 캡처 그룹.

단어 경계를 사용하면 단일 단어를 얻을 수 있습니다 ...

me@home ~  
$ echo "Where is my bar of soap?" | egrep "\bfoo\b|\bbar\b"  
Where is my bar of soap?  

me@home ~  
$ echo "What the foo happened here?" | egrep "\bfoo\b|\bbar\b"  
What the foo happened here?  

me@home ~  
$ echo "Boy, that sure is foobar\!" | egrep "\bfoo\b|\bbar\b"  
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top