renovations
|
@ -1,13 +1,18 @@
|
|||
# Жадный и ленивый режимы
|
||||
# Жадные и ленивые квантификаторы [todo]
|
||||
|
||||
Теперь время залезть "под капот" регулярных выражений и посмотреть, как происходит поиск.
|
||||
Квантификаторы -- с виду очень простая, но на самом деле очень хитрая штука.
|
||||
|
||||
Необходимо очень хорошо понимать, как именно происходит поиск, если конечно мы хотим искать что-либо сложнее чем <code class="pattern">/\d+/</code>.
|
||||
|
||||
Это понимание необходимо для того, чтобы искать что-либо сложнее чем <code class="pattern">/\d+/</code>.
|
||||
[cut]
|
||||
|
||||
Для примера рассмотрим задачу, которая часто возникает в типографике -- заменить кавычки вида `"..."` на "кавычки-лапки": `«...»`.
|
||||
Для примера рассмотрим задачу, которая часто возникает в типографике -- заменить в тексте кавычки вида `"..."` (их называют "английские кавычки") на "кавычки-ёлочки": `«...»`.
|
||||
|
||||
Шаблон, который мы будем использовать для поиска подстрок в кавычках, будет выглядеть так:
|
||||
Для этого нужно сначала найти все слова в таких кавычках.
|
||||
|
||||
Соотверствующее регулярное выражение может выглядеть так: <code class="pattern">/".+"/g</code>, то есть мы ищем кавычку, после которой один или более произвольный символ, и в конце опять кавычка.
|
||||
|
||||
Однако, если попробовать применить его на практике, даже на таком простом случае...
|
||||
|
||||
```js
|
||||
//+ run
|
||||
|
@ -15,38 +20,48 @@ var reg = /".+"/g;
|
|||
|
||||
var str = 'a "witch" and her "broom" is one';
|
||||
|
||||
alert( str.match(reg) );
|
||||
alert( str.match(reg) ); // "witch" and her "broom"
|
||||
```
|
||||
|
||||
Запустите этот пример...
|
||||
...Мы увидим, что оно работает совсем не так, как задумано!
|
||||
|
||||
Упс! Он не работает! Вместо того, чтобы найти два совпадения <code class="match">"witch"</code> и <code class="match">"broom"</code>, он находит одно: <code class="match">"witch" and her "broom"</code>.
|
||||
Вместо того, чтобы найти два совпадения <code class="match">"witch"</code> и <code class="match">"broom"</code>, оно находит одно: <code class="match">"witch" and her "broom"</code>.
|
||||
|
||||
Это как раз тот случай, когда *жадность* -- причина всех зол.
|
||||
|
||||
## Алгоритм поиска
|
||||
## Жадный поиск
|
||||
|
||||
Движок регулярных выражений пытается проверить строку на соответствие шаблону, начиная с самой первой, нулевой позиции. Если не получается, он идёт вперёд и пытается найти с 1й позиции и так далее.
|
||||
Чтобы найти совпадение, движок регулярных выражений обычно использует следующий алгоритм:
|
||||
|
||||
Чтобы сделать происходящее максимально наглядным и понятным, проследим, что именно он делает для паттерна <code class="pattern">".+"</code>.
|
||||
<ul>
|
||||
<li>Для каждой позиции в поисковой строке
|
||||
<ul>
|
||||
<li>Проверить совпадение на данной позиции
|
||||
<ul><li>Посимвольно, с учётом классов и квантификаторов сопоставив с ней регулярное выражение.</li></ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
Это общие слова, гораздо понятнее будет, если мы проследим, что именно он делает для регэкспа <code class="pattern">".+"</code>.
|
||||
|
||||
<ol>
|
||||
<li>Первый символ шаблона -- это кавычка <code class="pattern">"</code>.
|
||||
|
||||
Движок регулярных выражений пытается найти её на 0й позиции, но там совсем другой символ, поэтому на 0й позиции соответствия явно нет.
|
||||
Движок регулярных выражений пытается сопоставить её на 0й позиции в строке, но символ `a`, поэтому на 0й позиции соответствия явно нет.
|
||||
|
||||
Далее он переходит 1ю, 2ю позицию в исходной строке и, наконец, обнаруживает кавычку на 3й позиции:
|
||||
<img src="witch_greedy1.png">
|
||||
<img src="witch_greedy1.svg">
|
||||
</li>
|
||||
<li>Кавычка найдена, далее движок проверяет, есть ли соответствие для остальной части паттерна.
|
||||
|
||||
В данном случае следующий символ паттерна -- `.` (точка). Она обозначает "любой символ", так что следующая буква строки <code class="match">'w'</code> вполне подходит:
|
||||
<img src="witch_greedy2.png">
|
||||
<img src="witch_greedy2.svg">
|
||||
</li>
|
||||
<li>Далее "любой символ" повторяется, так как стоит квантификатор <code class="pattern">.+</code>. Движок регулярных выражений берёт один символ за другим, до тех пор, пока у него это получается.
|
||||
|
||||
В данном случае это означает "до конца строки":
|
||||
<img src="witch_greedy3.png">
|
||||
<img src="witch_greedy3.svg">
|
||||
</li>
|
||||
<li>Итак, текст закончился, движок регулярных выражений больше не может найти "любой символ", он закончил строить соответствие для <code class="pattern">.+</code> и очень рад по этому поводу.
|
||||
|
||||
|
|
Before Width: | Height: | Size: 546 B |
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="463px" height="117px" viewBox="0 0 463 117" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
|
||||
<!-- Generator: bin/sketchtool 1.3 (252) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>witch_greedy1.svg</title>
|
||||
<desc>Created with bin/sketchtool.</desc>
|
||||
<defs></defs>
|
||||
<g id="combined" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
|
||||
<g id="witch_greedy1.svg" sketch:type="MSArtboardGroup">
|
||||
<text id="a-"witch"-and-her-"b" sketch:type="MSTextLayer" font-family="Consolas" font-size="24" font-weight="normal" fill="#8A704D">
|
||||
<tspan x="20" y="82">a "witch" and her "broom" is one</tspan>
|
||||
</text>
|
||||
<text id="--"-----------------" sketch:type="MSTextLayer" font-family="Consolas" font-size="24" font-weight="normal">
|
||||
<tspan x="20" y="47" fill="#CB1E31"> " </tspan>
|
||||
<tspan x="72.78125" y="47" fill="#B8BAC1"> </tspan>
|
||||
<tspan x="85.9765625" y="47" fill="#CB1E31"> </tspan>
|
||||
</text>
|
||||
<rect id="Rectangle-1" stroke="#E8C48E" sketch:type="MSShapeGroup" x="45" y="20" width="15" height="77"></rect>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 551 B |
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="463px" height="117px" viewBox="0 0 463 117" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
|
||||
<!-- Generator: bin/sketchtool 1.3 (252) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>witch_greedy2.svg</title>
|
||||
<desc>Created with bin/sketchtool.</desc>
|
||||
<defs></defs>
|
||||
<g id="combined" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
|
||||
<g id="witch_greedy2.svg" sketch:type="MSArtboardGroup">
|
||||
<text id="a-"witch"-and-her-"b" sketch:type="MSTextLayer" font-family="Consolas" font-size="24" font-weight="normal" fill="#8A704D">
|
||||
<tspan x="20" y="82">a "witch" and her "broom" is one</tspan>
|
||||
</text>
|
||||
<text id="--".----------------" sketch:type="MSTextLayer" font-family="Consolas" font-size="24" font-weight="normal">
|
||||
<tspan x="20" y="47" fill="#CB1E31"> ".</tspan>
|
||||
<tspan x="72.78125" y="47" fill="#B8BAC1"> </tspan>
|
||||
<tspan x="85.9765625" y="47" fill="#CB1E31"> </tspan>
|
||||
</text>
|
||||
<rect id="Rectangle-1" stroke="#E8C48E" sketch:type="MSShapeGroup" x="45" y="20" width="29" height="77"></rect>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 569 B |
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="463px" height="117px" viewBox="0 0 463 117" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
|
||||
<!-- Generator: bin/sketchtool 1.3 (252) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>witch_greedy3.svg</title>
|
||||
<desc>Created with bin/sketchtool.</desc>
|
||||
<defs></defs>
|
||||
<g id="combined" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
|
||||
<g id="witch_greedy3.svg" sketch:type="MSArtboardGroup">
|
||||
<text id="a-"witch"-and-her-"b" sketch:type="MSTextLayer" font-family="Consolas" font-size="24" font-weight="normal" fill="#8A704D">
|
||||
<tspan x="20" y="82">a "witch" and her "broom" is one</tspan>
|
||||
</text>
|
||||
<text id="--"................." sketch:type="MSTextLayer" font-family="Consolas" font-size="24" font-weight="normal">
|
||||
<tspan x="20" y="47" fill="#CB1E31"> "......................</tspan>
|
||||
<tspan x="349.882812" y="47" fill="#D7343F">.......</tspan>
|
||||
<tspan x="442.25" y="47" fill="#CB1E31"> </tspan>
|
||||
</text>
|
||||
<rect id="Rectangle-1" stroke="#E8C48E" sketch:type="MSShapeGroup" x="45" y="20" width="402" height="77"></rect>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 573 B |
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="463px" height="117px" viewBox="0 0 463 117" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
|
||||
<!-- Generator: bin/sketchtool 1.3 (252) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>witch_greedy4.svg</title>
|
||||
<desc>Created with bin/sketchtool.</desc>
|
||||
<defs></defs>
|
||||
<g id="combined" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
|
||||
<g id="witch_greedy4.svg" sketch:type="MSArtboardGroup">
|
||||
<text id="a-"witch"-and-her-"b" sketch:type="MSTextLayer" font-family="Consolas" font-size="24" font-weight="normal" fill="#8A704D">
|
||||
<tspan x="20" y="82">a "witch" and her "broom" is one</tspan>
|
||||
</text>
|
||||
<text id="--"................." sketch:type="MSTextLayer" font-family="Consolas" font-size="24" font-weight="normal">
|
||||
<tspan x="20" y="47" fill="#CB1E31"> "......................</tspan>
|
||||
<tspan x="349.882812" y="47" fill="#D7343F">......</tspan>
|
||||
<tspan x="429.054688" y="47" fill="#B9BAC1">"</tspan>
|
||||
<tspan x="442.25" y="47" fill="#CB1E31"> </tspan>
|
||||
</text>
|
||||
<rect id="Rectangle-1" stroke="#E8C48E" sketch:type="MSShapeGroup" x="45" y="20" width="384" height="77"></rect>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 579 B |
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="463px" height="117px" viewBox="0 0 463 117" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
|
||||
<!-- Generator: bin/sketchtool 1.3 (252) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>witch_greedy5.svg</title>
|
||||
<desc>Created with bin/sketchtool.</desc>
|
||||
<defs></defs>
|
||||
<g id="combined" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
|
||||
<g id="witch_greedy5.svg" sketch:type="MSArtboardGroup">
|
||||
<text id="a-"witch"-and-her-"b" sketch:type="MSTextLayer" font-family="Consolas" font-size="24" font-weight="normal" fill="#8A704D">
|
||||
<tspan x="20" y="82">a "witch" and her "broom" is one</tspan>
|
||||
</text>
|
||||
<text id="--"................." sketch:type="MSTextLayer" font-family="Consolas" font-size="24" font-weight="normal">
|
||||
<tspan x="20" y="47" fill="#CB1E31"> "......................</tspan>
|
||||
<tspan x="349.882812" y="47" fill="#D7343F">.....</tspan>
|
||||
<tspan x="415.859375" y="47" fill="#B9BAC1">".</tspan>
|
||||
<tspan x="442.25" y="47" fill="#CB1E31"> </tspan>
|
||||
</text>
|
||||
<rect id="Rectangle-1" stroke="#E8C48E" sketch:type="MSShapeGroup" x="45" y="20" width="371" height="77"></rect>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 581 B |
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="463px" height="117px" viewBox="0 0 463 117" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
|
||||
<!-- Generator: bin/sketchtool 1.3 (252) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>witch_greedy6.svg</title>
|
||||
<desc>Created with bin/sketchtool.</desc>
|
||||
<defs></defs>
|
||||
<g id="combined" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
|
||||
<g id="witch_greedy6.svg" sketch:type="MSArtboardGroup">
|
||||
<text id="a-"witch"-and-her-"b" sketch:type="MSTextLayer" font-family="Consolas" font-size="24" font-weight="normal" fill="#8A704D">
|
||||
<tspan x="20" y="82">a "witch" and her "broom" is one</tspan>
|
||||
</text>
|
||||
<text id="--"................." sketch:type="MSTextLayer" font-family="Consolas" font-size="24" font-weight="normal">
|
||||
<tspan x="20" y="47" fill="#CB1E31"> "....................."</tspan>
|
||||
<tspan x="349.882812" y="47" fill="#B9BAC1">.......</tspan>
|
||||
<tspan x="442.25" y="47" fill="#CB1E31"> </tspan>
|
||||
</text>
|
||||
<rect id="Rectangle-1" stroke="#E8C48E" sketch:type="MSShapeGroup" x="45" y="20" width="306" height="77"></rect>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 566 B |
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="463px" height="117px" viewBox="0 0 463 117" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
|
||||
<!-- Generator: bin/sketchtool 1.3 (252) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>witch_lazy3.svg</title>
|
||||
<desc>Created with bin/sketchtool.</desc>
|
||||
<defs></defs>
|
||||
<g id="combined" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
|
||||
<g id="witch_lazy3.svg" sketch:type="MSArtboardGroup">
|
||||
<text id="a-"witch"-and-her-"b" sketch:type="MSTextLayer" font-family="Consolas" font-size="24" font-weight="normal" fill="#8A704D">
|
||||
<tspan x="20" y="82">a "witch" and her "broom" is one</tspan>
|
||||
</text>
|
||||
<text id="--"."---------------" sketch:type="MSTextLayer" font-family="Consolas" font-size="24" font-weight="normal">
|
||||
<tspan x="20" y="47" fill="#CB1E31"> ".</tspan>
|
||||
<tspan x="72.78125" y="47" fill="#B8BAC1">"</tspan>
|
||||
<tspan x="85.9765625" y="47" fill="#CB1E31"> </tspan>
|
||||
</text>
|
||||
<rect id="Rectangle-1" stroke="#E8C48E" sketch:type="MSShapeGroup" x="45" y="20" width="29" height="77"></rect>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 579 B |
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="463px" height="117px" viewBox="0 0 463 117" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
|
||||
<!-- Generator: bin/sketchtool 1.3 (252) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>witch_lazy4.svg</title>
|
||||
<desc>Created with bin/sketchtool.</desc>
|
||||
<defs></defs>
|
||||
<g id="combined" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
|
||||
<g id="witch_lazy4.svg" sketch:type="MSArtboardGroup">
|
||||
<text id="a-"witch"-and-her-"b" sketch:type="MSTextLayer" font-family="Consolas" font-size="24" font-weight="normal" fill="#8A704D">
|
||||
<tspan x="20" y="82">a "witch" and her "broom" is one</tspan>
|
||||
</text>
|
||||
<text id="--".."--------------" sketch:type="MSTextLayer" font-family="Consolas" font-size="24" font-weight="normal">
|
||||
<tspan x="20" y="47" fill="#CB1E31"> "..</tspan>
|
||||
<tspan x="85.9765625" y="47" fill="#B8BAC1">"</tspan>
|
||||
<tspan x="99.171875" y="47" fill="#CB1E31"> </tspan>
|
||||
</text>
|
||||
<rect id="Rectangle-1" stroke="#E8C48E" sketch:type="MSShapeGroup" x="45" y="20" width="41" height="77"></rect>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 611 B |
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="463px" height="117px" viewBox="0 0 463 117" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
|
||||
<!-- Generator: bin/sketchtool 1.3 (252) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>witch_lazy6.svg</title>
|
||||
<desc>Created with bin/sketchtool.</desc>
|
||||
<defs></defs>
|
||||
<g id="combined" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
|
||||
<g id="witch_lazy6.svg" sketch:type="MSArtboardGroup">
|
||||
<text id="a-"witch"-and-her-"b" sketch:type="MSTextLayer" font-family="Consolas" font-size="24" font-weight="normal" fill="#8A704D">
|
||||
<tspan x="20" y="82">a "witch" and her "broom" is one</tspan>
|
||||
</text>
|
||||
<text id="--"....."---------"." sketch:type="MSTextLayer" font-family="Consolas" font-size="24" font-weight="normal" fill="#CB1E31">
|
||||
<tspan x="20" y="47"> "....." "....." </tspan>
|
||||
</text>
|
||||
<rect id="Rectangle-1" stroke="#E8C48E" sketch:type="MSShapeGroup" x="45" y="20" width="95" height="77"></rect>
|
||||
<rect id="Rectangle-2" stroke="#E8C48E" sketch:type="MSShapeGroup" x="256" y="20" width="95" height="77"></rect>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.4 KiB |