정규 표현식의 맥락에서 '게으른'과 '욕심쟁이'는 무엇을 의미합니까?
누군가이 두 용어를 이해할 수있는 방식으로 설명 할 수 있습니까?
탐욕은 가능한 한 많이 소비 할 것입니다. 에서 http://www.regular-expressions.info/repeat.html 우리는 함께 HTML 태그를 일치하도록 노력의 예를 참조하십시오 <.+>
. 다음이 있다고 가정하십시오.
<em>Hello World</em>
당신은 그 생각 <.+>
( .
수단 이 아닌 개행 문자 및 +
수단 중 하나 이상 )에만 일치합니다 <em>
과를 </em>
현실에 매우 욕심 때, 첫 번째에서 이동 <
마지막에 >
. 이것은 <em>Hello World</em>
당신이 원하는 것이 아니라 일치한다는 것을 의미합니다 .
게으 르면 ( <.+?>
) 이것을 방지 할 수 있습니다. ?
이후에 를 추가하면 가능한 한 몇 번+
반복하도록 지시 하므로 처음 으로 나타나는 부분은 일치를 중지하려는 위치입니다.>
정규식을 탐색하는 데 도움이되는 훌륭한 도구 인 RegExr 을 다운로드하는 것이 좋습니다 . 항상 사용합니다.
'Greedy' 는 가능한 가장 긴 문자열과 일치 함을 의미합니다.
'Lazy' 는 가능한 가장 짧은 문자열과 일치 함을 의미합니다.
예를 들어, 욕심 h.+l
경기 'hell'
에서 'hello'
하지만 게으른 h.+?l
경기 'hel'
.
+-------------------+-----------------+------------------------------+
| Greedy quantifier | Lazy quantifier | Description |
+-------------------+-----------------+------------------------------+
| * | *? | Star Quantifier: 0 or more |
| + | +? | Plus Quantifier: 1 or more |
| ? | ?? | Optional Quantifier: 0 or 1 |
| {n} | {n}? | Quantifier: exactly n |
| {n,} | {n,}? | Quantifier: n or more |
| {n,m} | {n,m}? | Quantifier: between n and m |
+-------------------+-----------------+------------------------------+
을 추가하다 ? 수량 자에게 불쾌감을 줄 수 있습니다.
예 :
테스트 문자열 : 유래
욕심 레그 식 : s.*o
출력 : stackoverflo w
지연 레그 식 : s.*?o
출력 : stacko verflow
욕심은 표현이 가능한 한 큰 그룹과 일치한다는 것을 의미하고, 게으름은 가능한 가장 작은 그룹과 일치한다는 것을 의미합니다. 이 문자열의 경우 :
abcdefghijklmc
그리고이 표현은 :
a.*c
욕심 많은 경기는 전체 문자열과 일치하고 게으른 경기는 첫 번째 경기와 일치합니다 abc
.
내가 아는 한 대부분의 정규식 엔진은 기본적으로 욕심입니다. 수량 자 끝에 물음표를 추가하면 지연 일치가 활성화됩니다.
@Andre S가 의견에서 언급했듯이.
- 탐욕 : 조건이 충족되지 않을 때까지 계속 검색하십시오.
- 게으른 : 조건이 충족되면 검색을 중지합니다.
탐욕스럽고 게으른 것에 대해서는 아래의 예를 참조하십시오.
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test {
public static void main(String args[]){
String money = "100000000999";
String greedyRegex = "100(0*)";
Pattern pattern = Pattern.compile(greedyRegex);
Matcher matcher = pattern.matcher(money);
while(matcher.find()){
System.out.println("I'm greeedy and I want " + matcher.group() + " dollars. This is the most I can get.");
}
String lazyRegex = "100(0*?)";
pattern = Pattern.compile(lazyRegex);
matcher = pattern.matcher(money);
while(matcher.find()){
System.out.println("I'm too lazy to get so much money, only " + matcher.group() + " dollars is enough for me");
}
}
}
결과는 다음과 같습니다.
나는 탐욕스럽고 100000000 달러를 원합니다. 이것이 내가 얻을 수있는 가장 큰 것입니다.
너무 많은 돈을 벌기에는 게으르다. 100 달러면 충분하다.
www.regular-expressions.info 에서 가져옴
Greediness : Greedy 한정자는 먼저 토큰을 가능한 한 여러 번 반복하려고 시도하고 전반적인 일치를 찾기 위해 엔진 역 추적에 따라 점차적으로 일치를 포기합니다.
게으름 : 게으른 수량자는 먼저 필요한만큼 토큰을 반복하고 엔진이 정규 표현식을 통해 역 추적 할 때 전체 일치를 찾기 위해 점차적으로 일치를 확장합니다.
에서 정규 표현식
정규 표현식의 표준 수량자는 욕심이 많으므로 가능한 한 많이 일치하므로 나머지 정규 표현식과 일치하는 데 필요한만큼만 반환합니다.
게으른 수량자를 사용하면식이 최소 일치를 먼저 시도합니다.
욕심은 패턴이 남아 더 이상 보이지 않을 때까지 패턴을 소비한다는 것을 의미합니다.
지연은 요청한 첫 번째 패턴을 발견하자마자 중지됩니다.
자주 발생하는 한 가지 예 \s*-\s*?
는 정규식입니다.([0-9]{2}\s*-\s*?[0-9]{7})
첫 번째 \s*
는 욕심으로 분류되며 *
숫자가 발생한 후 가능한 많은 공백을 찾은 다음 대시 문자 "-"를 찾습니다. \s*?
현재로 인해 두 번째 가 게으른 곳 *?
은 첫 번째 공백 문자를보고 거기에서 멈추는 것을 의미합니다.
욕심 매칭. 정규 표현식의 기본 동작은 욕심입니다. 즉, 작은 부분이 구문 적으로 충분했을 때에도 패턴에 맞을 때까지 가능한 한 많이 추출하려고 시도합니다.
예:
import re
text = "<body>Regex Greedy Matching Example </body>"
re.findall('<.*>', text)
#> ['<body>Regex Greedy Matching Example </body>']
'>'가 처음 나타날 때까지 일치하는 대신 전체 문자열을 추출했습니다. 이것은 정규 욕심 또는 정규식의 '모두 가져 가기'행동입니다.
반면에 게으른 일치 는 '가능한 한 적게 가져갑니다'. 이것은 ?
패턴의 끝에 a 를 추가하여 수행 할 수 있습니다 .
예:
re.findall('<.*?>', text)
#> ['<body>', '</body>']
첫 번째 일치 항목 만 검색하려면 검색 방법을 대신 사용하십시오.
re.search('<.*?>', text).group()
#> '<body>'
출처 : 파이썬 정규식 예제
예제로 가장 잘 나타납니다. 끈. 192.168.1.1 및 욕심 많은 정규 표현식 \ b. + \ b 이것이 첫 번째 옥텟을 줄 것이라고 생각할 수도 있지만 실제로는 전체 문자열과 일치합니다. 왜!!! . +는 욕심과 욕심 일치는 문자열의 끝에 도달 할 때까지 '192.168.1.1'의 모든 문자와 일치합니다. 이것은 중요한 비트입니다! 이제 세 번째 토큰과 일치하는 것을 찾을 때까지 한 번에 한 문자 씩 역 추적하기 시작합니다 (\ b).
문자열에 4GB 텍스트 파일과 192.168.1.1이 시작되면이 역 추적이 어떻게 문제를 일으키는 지 쉽게 알 수 있습니다.
정규식을 욕심없는 (게으른) 만들려면 욕심 많은 검색 뒤에 물음표를 넣으십시오. 예를 들어 *? ?? +? 토큰 2 (+?)가 일치하는 것을 찾고 정규식이 문자를 따라 이동 한 다음 토큰 2 (+?)가 아닌 다음 토큰 (\ b)을 시도합니다. 그래서 그것은 진지하게 섬뜩합니다.
파싱 할 때 더 빠른 것을 찾는 사람이 여기에 있다면 :
정규 표현식 성능에 대한 일반적인 오해는 게으른 수량 자 (비 욕심, 마지 못함, 최소 또는 욕심이라고도 함)가 욕심 많은 동등 물보다 빠르다는 것입니다. 일반적으로 사실은 아니지만 중요한 한정자가 있습니다. 실제로 게으른 정량자는 종종 더 빠릅니다.
주요 불량배 발췌
다음 동작을 이해하십시오.
var input = "0014.2";
Regex r1 = new Regex("\\d+.{0,1}\\d+");
Regex r2 = new Regex("\\d*.{0,1}\\d*");
Console.WriteLine(r1.Match(input).Value); // "0014.2"
Console.WriteLine(r2.Match(input).Value); // "0014.2"
input = " 0014.2";
Console.WriteLine(r1.Match(input).Value); // "0014.2"
Console.WriteLine(r2.Match(input).Value); // " 0014"
input = " 0014.2";
Console.WriteLine(r1.Match(input).Value); // "0014.2"
Console.WriteLine(r2.Match(input).Value); // ""
'development' 카테고리의 다른 글
SSH를 통한 파일 전송 (0) | 2020.02.16 |
---|---|
모든 레코드를 반환하는 Elasticsearch 쿼리 (0) | 2020.02.16 |
NSOperation 및 그랜드 센트럴 디스패치 (0) | 2020.02.16 |
SQL Server에 .NET의 Math.Max와 같은 두 가지 값을 취하는 Max 함수가 있습니까? (0) | 2020.02.16 |
NSDictionary 또는 NSMutableDictionary에 키가 있는지 확인하는 방법? (0) | 2020.02.16 |