문제
약간의 regex 도움을 찾고 있습니다. 문자열과 일치하는 표현을 설계하고 싶습니다.foo" 또는 "술집", 그러나 둘 다 아닙니다"foo" 그리고 "술집"
내가 같은 일을한다면 ...
/((foo)|(bar))/
일치 할거야 "foobar". 내가 찾고있는 것이 아닙니다. 그래서, 한 용어 나 다른 용어가있을 때만 Regex 일치를 어떻게 만들 수 있습니까?
감사!
해결책
당신은 단일 정규식으로 이것을 할 수 있지만, 나는 당신이 같은 일을하는 가독성을 위해 제안합니다 ...
(/foo/ and not /bar/) || (/bar/ and not /foo/)
다른 팁
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 대신 코드로 그것을 할 것입니다. 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"