Основные понятия и элементы


Регулярные выражения

        Tcl предоставляет две команды для сравнения строк регулярных выражений в стиле egrep: regexp и regsub.

        Регулярное выражение состоит из ни одной или более ветвей (branch), разделенных символом «|». Оно совпадает с любым выражением, которое совпадает с одной из ветвей.

        Ветвь состоит из одного или более кусков (piece), соединённых друг с другом. Она совпадает с выражением, которое состоит из тождества для первого куска, следом за которым идет тождество для второго куска, и т.д.

        Кусок состоит из атома со следующим за ним необязательным символом *, + или ?. Атом с последующим символом * совпадает с последовательностью из одного или более тождества для этого атома. Атом с символом + после него совпадает с последовательностью из одного или более тождества для этого атома. Атом с символом ? после него совпадает с последовательностью из одного тождества для этого атома или пустой строкой.

        Атом может быть регулярным выражением в скобках (в этом случае оно совпадает с тождеством для этого регулярного выражения), интервалом, символом «.» (совпадающим с одним любым символом), «^» (совпадающим с нулевой строкой в начале вводимой строки), «$» (совпадающим с нулевой строкой в конце вводимой строки), «\» с последующим одним символом (совпадающим с этим символом), или одним символом без какого-либо иного смысла (совпадающим с этим символом).

        Интервал есть последовательность символов, заключенная в квадратные скобки. Он обычно совпадает с любым символом из этого интервала. Если последовательность начинается с символа ^, то она совпадает с любым символом не из числа остальных символов. Если два символа в последовательности разделены символом -, то это краткая форма для обозначения всех символов между этими двумя (например, [0-9] совпадает с любой десятичной цифрой). Для того, чтобы включить в последовательность символ «]», следует поставить его на место первого в последовательности (следом за возможным символом «^»). Для включения в последовательность символа «-» следует сделать его первым или последним символом.

        Если регулярное выражение совпадает с двумя разными частями строки, она будет совпадать с той, которая раньше начинается. Если обе начинаются в одном и том же месте, то это неопределенный (тяжелый) случай. Его можно объяснить следующим образом.

        В общем, возможные исходы в списке ветвей рассматриваются слева направо. Исходы для *, + и ? рассматриваются в порядке убывания длины. Вложенные конструкции рассматриваются извне вовнутрь (from the outermost in), и составленные (concatenated) конструкции рассматриваются слева направо. Будет выбрано то из тождеств, которое будет отвечать самому раннему из исходов в первом выборе. Если предстоит несколько выборов, то следующее сравнение будет сделано таким же образом (самый ранний из исходов), в зависимости от решения при первом выборе, и так далее.

        Например, (ab|f)b*c может совпадать с abc одним из двух способов. Первый выбор делается между ab и а; поскольку ab стоит раньше и ведет к успешному совпадению, то оно будет выбрано. Поскольку b уже закрыто, то b* должно совпасть со своим крайним исходом — пустой строкой, чтобы не конфликтовать с предыдущим выбором.

        В частном случае, когда нет ни одного разделителя ветвей «|» и присутствует только один символ *, + или ?, общий результат будет следующим: будет выбрано самое длинное тождество из всех возможных. Таким образом, сравнение ab* с xabbbby даст результат abbbb. Зато если ab* будет сравниваться с xabyabbbz, то результатом будет считаться ab, находящееся сразу за х, в соответствии с правилом первого совпадения из всех возможных. В действительности, решение о том, откуда начинать сравнивать, есть первый выбор, который надо сделать. Этому выбору должны подчиняться последующие шаги, даже они ведут к менее предпочтительному результату.
Hosted by uCoz