정규식까지만 포함되지 않음


81

정규식의 경우 검색 구문은 무엇입니까? 좀 좋아 :

Haystack:
The quick red fox jumped over the lazy brown dog

Expression:
.*?quick -> and then everything until it hits the letter "z" but do not include z

답변:


161

"검색 할 때까지 검색 X하지만 포함하지 않음 "을 명시 적으로 표현하는 방법 X은 다음과 같습니다.

(?:(?!X).)*

어디에 X어떤 정규 표현식이 될 수 있습니다.

그러나 귀하의 경우 이것은 과잉 일 수 있습니다-여기서 가장 쉬운 방법은

[^z]*

이것은 z다음을 제외한 모든 것과 일치 하므로 다음 바로 전에 중지 z됩니다.

그래서 .*?quick[^z]*일치 The quick fox jumps over the la합니다.

그러나, 곧 당신이 피려 하나 이상의 간단한 편지를 가지고 (?:(?!X).)*예를 들어, 활동하기 시작

(?:(?!lazy).)*-단어의 시작 부분까지 일치합니다 lazy.

이것은 lookahead assertion , 더 구체적으로 부정적인 lookahead를 사용합니다.

.*?quick(?:(?!lazy).)*일치 The quick fox jumps over the합니다.

설명:

(?:        # Match the following but do not capture it:
 (?!lazy)  # (first assert that it's not possible to match "lazy" here
 .         # then match any character
)*         # end of group, zero or more repetitions.

또한 키워드를 검색 할 때 단어 경계 앵커로 키워드를 둘러싸고 싶을 수 있습니다. \bfox\b는 전체 단어 만 일치 fox하지만 foxy.

노트

일치 할 텍스트에 줄 바꿈도 포함될 수있는 경우 정규식 엔진의 "점 모두 일치"옵션을 설정해야합니다. 일반적으로 (?s)정규식 앞에 추가 하여 이를 달성 할 수 있지만 모든 정규식 엔진 (특히 JavaScript)에서는 작동하지 않습니다.

대체 솔루션 :

대부분의 경우 지연 수량자를 사용하는 더 간단하고 읽기 쉬운 솔루션을 사용할 수도 있습니다. 수량 자에 a ?를 추가 *하면 현재 위치에서 가능한 한 적은 수의 문자를 일치 시키려고합니다.

.*?(?=(?:X)|$)

임의의 수의 문자와 일치 X하며 (정규식이 될 수 있음) 바로 앞 또는 문자열의 끝 ( X일치하지 않는 경우) 에서 중지 됩니다. 이 작업을 수행하려면 "dot match all"옵션을 설정해야 할 수도 있습니다. (참고 : X대체에서 안정적으로 격리하기 위해 캡처하지 않는 그룹을 추가했습니다. )


+1 정말 좋은 답변입니다. 안타깝게도에서 작동하지 grep않지만이 답변 은 작동합니다.
Alexandre Lavoie

@AlexandreLavoie : 흥미 롭군요. 다른 하나가 작동해야하고 이것이 작동하지 않는 이유는 무엇입니까? 둘 다 예측 어설 션을 사용합니다. 아마도 그것은 단지 때문에의의 (?:...)비 캡처 그룹? 함께 작동합니까 ((?!X).)*?
팀 Pietzcker

1
정말 모르겠습니다. 저는 정규식 전문가도 아니고 grep도 아닙니다. 나는 grepSQL의 mysql bin transformet에서 하나의 데이터베이스에 대한 요청 만 필터링 하는 데 사용 했습니다. 여기에 짐승은 다음과 같습니다grep -Po "(?s)use database_to_keep(.*?)(?=^use)" mysql-bin.000045.sql > filtered.sql
알렉상드르 라보

내가 쳤을 때 이후 bash는 충돌처럼 보이는 Up키, 마지막 명령은 내가 사용했던 하나되지 않습니다 :grep -Po "(?s)use database_to_keep(.*?)(?:(?!^use).)*" mysql-bin.000045.sql > filtered.sql
알렉상드르 라보

1
좋은 편집, @ 팀, 그냥 추가 $교체 : 대안 .*?(?=X)으로.*?(?=X|$)
Wiktor Stribiżew

15

내다 정규식 구문은 당신이 당신의 목표를 달성하는 데 도움이 될 수 있습니다. 따라서 귀하의 예에 대한 정규식은

.*?quick.*?(?=z)

그리고 미리보기 .*?전에 지연 일치를 확인하는 것이 중요합니다 (?=z). 표현식 은 문자 가 처음 나타날 때까지 하위 문자열과 일치합니다 z.

다음은 C # 코드 샘플입니다.

const string text = "The quick red fox jumped over the lazy brown dogz";

string lazy = new Regex(".*?quick.*?(?=z)").Match(text).Value;
Console.WriteLine(lazy); // The quick red fox jumped over the la

string greedy = new Regex(".*?quick.*(?=z)").Match(text).Value;
Console.WriteLine(greedy); // The quick red fox jumped over the lazy brown dog

0

이 시도

(.*?quick.*?)z

3
여기에는 일치하는 "z"가 포함되며, 이는 질문자가 피하고 싶어하는 것입니다. 아마도 정규식은 '|'의 용어가 될 것입니다. 대체 및 해당 대체 정규식은 여러 일치를 수행하는 데 사용됩니다. "z"가 대체 용어의 다른 용어 와 일치하는 문자열의 시작 인 경우 "z"가 이미 현재 일치 항목에서 사용 되었기 때문에이 일치 항목은 상실됩니다.
Szczepan Hołyszewski 2015-08-27
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.