projman/hlp/ru/tcl/regexp.html
2018-02-05 17:23:37 +03:00

193 lines
12 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE HTML PUBLIC -//W3C//DTD HTML 4.01 Transitional//EN>
<html>
<head>
<title>regexp</title>
</head>
<body>
<h1>regexp</h1>
<p>Сравнивает строку и регулярное выражение.</p>
<h2>СИНТАКСИС</h2>
<pre>
<strong>regexp</strong> ?<em>switches</em>? <em>exp</em> <em>string</em> ?<em>matchVar</em>? ?<em>subMatchVar</em> <em>subMatchVar</em>...?
</pre>
<h2>ОПИСАНИЕ</h2>
<p>Команда определяет, соответствует ли регулярное
выражение<em>exp</em> какой-либо части строки <em>string</em> или
всей строке, и возвращает <strong>1</strong>, если соответствует, и
<strong>0</strong> - в противном случае.</p>
<p>Если в команде указаны дополнительные аргументы после
<em>string</em>, они считаются именами переменных, в которые
возвращается информация о том, какие именно части строки
соответствуют регулярным выражениям. Переменной присваивается
значение, состоящее из части строки, соответствующей всему
регулярному выражению. Самой левой в списке переменной
<em>subMatchVar</em> присваивается значение, состоящее из части
строки, которая соответствует самому левому заключенному в
скобки выражению в составе <em>exp</em>. Следующей переменной
subMatchVar присваивается значение, соответствующее следующему
заключенному в скобки выражению, и так далее.</p>
<p>Если первые аргументы команды начинаются с <strong>-</strong>, они
считаются опциями команды. Ниже перечислены возможные опции.</p>
<dl>
<dt><strong>-nocase</strong></dt>
<dd>При сравнении не различает буквы в верхнем и нижнем
регистре.</dd>
<dt><strong>-indices</strong></dt>
<dd>В переменных <em>subMatchVars</em> сохраняются не части
строки, а списки из двух десятичных чисел - индексов начала и
конца соответствующей области строки.</dd>
<dt><strong>--</strong></dt>
<dd>Означает конец опций. следующий аргумент будет
рассматриваться как <em>exp</em>, даже если он начинается с
<strong>-</strong>.</dd>
</dl>
<p>Если в команде указано больше переменных <em>subMatchVar</em>,
чем выражений в скобках в <em>exp</em>, или если для одного из
выражений не удалось найти соответствующую ему часть строки, то
соответствующей переменной будет присвоено значение <strong>-1</strong>
или пустая строка, в зависимости от того, была ли задана опция
<strong>-indices</strong>.</p>
<h2><a name=РЕГУЛЯРНЫЕ></a>РЕГУЛЯРНЫЕ ВЫРАЖЕНИЯ</h2>
<p>Регулярное выражение состоит из ни одной или более
<em>ветвей</em> (branch), разделенных символом '<strong>|</strong>'. Строка
соответствует выражению, если она соответствует одной из его
ветвей.</p>
<p>Ветвь состоит из одной или более <em>частей</em> (piece),
соединенных друг с другом. строка соответствует ветви, если ее
можно разбить на подстроки таким образом, что начальная
подстрока соответствует первой части ветви, следующая подстрока
- следующей части ветви и так далее.</p>
<p>Часть состоит из атома со следующим за ним необязательным
символом '*', '<strong>+</strong>' или '<strong>?</strong>'. Атом с последующим
символом <strong>*</strong> соответствует любой последовательности из нуля
или более подстрок, каждая из которых соответствует атому. Атом
с символом '<strong>+</strong>' после него соответствует любой
последовательности из одной или более подстрок, каждая из
которых соответствует атому. Атом с символом '<strong>?</strong>' после
него соответствует подстроке, которая соответствует атому, или
пустой строке.</p>
<p>Атом может быть регулярным выражением в скобках (в этом случае
он соответствует любой строке, которая соответствует этому
регулярному выражению), <em>интервалом</em> (см. ниже), символом
'<strong>.</strong>' (соответствует ровно одному произвольному символу),
'<strong>^</strong>' (соответствует нулевой строке в начале
<em>string</em>), '<strong>$</strong>' (соответствует нулевой строке в конце
<em>string</em>), '<strong>\</strong>' с последующим одним символом
(соответствует этому символу), или одним символом без
какого-либо иного смысла (соответствует этому символу).</p>
<p><em>Интервал</em> есть последовательность символов, заключенная в
квадратные скобки. Он обычно соответствует любому символу из
этого интервала. Если последовательность начинается с символа
'<strong>^</strong>', то она соответствует любому символу, кроме символов,
стоящих далее в последовательности. Если два символа в
последовательности разделены символом '<strong>-</strong>', то это краткая
форма для обозначения всех ASCII символов между этими двумя
(например, '[0-9]' соответствует любой десятичной цифре). Для
того, чтобы включить в последовательность символ '<strong>]</strong>',
следует поставить его на место первого в последовательности
(следом за возможным символом '<strong>^</strong>'). Для включения в
последовательность символа '<strong>-</strong>' следует сделать его первым
или последним символом.</p>
<h2>ВЫБОР ИЗ АЛЬТЕРНАТИВНЫХ СОСТОЯНИЙ</h2>
<p>Вообще говоря, регулярное выражение может соответствовать
строке несколькими различными способами. Например, рассмотрим
выражение</p>
<pre>
regexp (a*)b* aabaaabb x y
</pre>
<p>В соответствии с описанными выше правилами переменные <strong>x</strong>
и <strong>y</strong> могут принять значение <strong>aabb</strong> и <strong>aa</strong>,
<strong>aaab</strong> и <strong>aaa</strong>, <strong>ab</strong> и <strong>a</strong> или одну из еще
нескольких возможных комбинаций. Чтобы избежать этой
потенциальной неопределенности команда <strong>regexp</strong> выбирает
между возможными вариантами по правилу &quot;первый и самый
длинный&quot;. Другими словами, строка и регулярное выражение
просматриваются слева направо, при этом выбирается часть строки
максимально возможной длины. Говоря точнее, при выборе
используются следующие правила в порядке убывания
приоритета.</p>
<table>
<tr>
<td>[1]</td>
<td><p>Если регулярное выражение соответствует двум разным
частям строки, выбирается та часть, которая раньше
начинается.</p>
<p>Если обе начинаются в одном и том же месте, то это
неопределенный (тяжелый) случай. Его можно объяснить
следующим образом.</p>
</td>
</tr>
<tr>
<td>[2]</td>
<td>Если регулярное выражение содержит символы <strong>|</strong> (то
есть состоит из нескольких ветвей), то будет выбрана самая
левая ветвь, которой что-либо соответствует.</td>
</tr>
<tr>
<td>[3]</td>
<td>Для выражений, содержащих '<strong>*</strong>', '<strong>+</strong>' и
'<strong>?</strong>', выбираются самые длинные фрагменты строки,
соответствующие им.</td>
</tr>
<tr>
<td><a name=rule4></a>[4]</td>
<td>Компоненты выражений рассматриваются слева направо.</td>
</tr>
</table>
<p>В приведенном выше примере <strong>(a*)b*</strong> соответствует
<strong>aab</strong>, так как для <strong>(a*)</strong> выбирается первый
соответствующий ему фрагмент, то есть начальные <strong>aa</strong>, а
затем для <strong>b*</strong> выбирается следующий символ
<strong>b</strong>. Рассмотрим еще один пример:</p>
<pre>
regexp (ab|a)(b*)c abc x y z
</pre>
<p>После выполнения команды переменная <strong>x</strong> будет содержать
значение <strong>abc</strong>, переменная <strong>y</strong> - <strong>ab</strong> и
переменная <strong>z</strong> будет содержать пустую строку. Правило <a
href=#rule4>[4]</a> определяет, что поиск начнется с выражения
<strong>(ab|a)</strong>, а правило [2], что поиск начнется с подвыражения
ab. Поэтому символ <strong>b</strong> в строке будет использован, и
выражение <strong>(b*)</strong> будет соответствовать пустой строке.</p>
</body>
</html>