renovations

This commit is contained in:
Ilya Kantor 2015-03-06 17:10:55 +03:00
parent 2022aafc13
commit dceccedb58
60 changed files with 1730 additions and 272 deletions

View file

@ -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> и очень рад по этому поводу.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 546 B

View file

@ -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-&quot;witch&quot;-and-her-&quot;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="--&quot;-----------------" 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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 551 B

View file

@ -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-&quot;witch&quot;-and-her-&quot;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="--&quot;.----------------" 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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 569 B

View file

@ -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-&quot;witch&quot;-and-her-&quot;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="--&quot;................." 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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 573 B

View file

@ -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-&quot;witch&quot;-and-her-&quot;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="--&quot;................." 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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 579 B

View file

@ -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-&quot;witch&quot;-and-her-&quot;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="--&quot;................." 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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 581 B

View file

@ -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-&quot;witch&quot;-and-her-&quot;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="--&quot;................." 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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 566 B

View file

@ -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-&quot;witch&quot;-and-her-&quot;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="--&quot;.&quot;---------------" 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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 579 B

View file

@ -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-&quot;witch&quot;-and-her-&quot;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="--&quot;..&quot;--------------" 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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 611 B

View file

@ -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-&quot;witch&quot;-and-her-&quot;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="--&quot;.....&quot;---------&quot;." 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