Spec-Zone.ru › Nim 1

re

Поддержка регулярных выражений в Nim.

Этот модуль реализован путём обертки над библиотекой C PCRE (Perl-совместимые регулярные выражения). Это означает, что ваше приложение будет зависеть от лицензии библиотеки PCRE при использовании этого модуля, что, однако, не должно вызывать проблем. Лицензия PCRE:

Лицензия библиотеки PCRE

PCRE — это библиотека функций для поддержки регулярных выражений, синтаксис и семантика которых максимально приближены к языку программирования Perl 5.

Разработал Филип Хэйзел
Copyright (c) 1997-2005 Университет Кембриджа


Перераспределение и использование в исходной и двоичной формах, с изменениями или без них, разрешены при соблюдении следующих условий:

  • Перераспределения исходного кода должны содержать вышеуказанное уведомление об авторских правах, этот список условий и следующее ограничение.
  • Перераспределения в двоичной форме должны воспроизводить вышеуказанное уведомление об авторских правах, этот список условий и следующее ограничение в документации и/или других материалах, поставляемых с распространением.
  • Имя Университета Кембриджа или имена его авторов не могут использоваться для поддержки или продвижения продуктов, полученных из данного программного обеспечения, без предварительного письменного разрешения.

ДАННОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ ПОЛУЧАТЕЛЯМИ АВТОРСКИХ ПРАВ И СОТРУДНИКАМИ «КАК ЕСТЬ», И ЛЮБЫЕ ЯВНЫЕ ИЛИ ПОДРАЗУМЕВАЮЩИЕСЯ ГАРАНТИИ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ИМИ, ПОДРАЗУМЕВАЮЩИЕ ГАРАНТИИ ТОРГОВОЙ ПРИГОДНОСТИ И ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННОЙ ЦЕЛИ, ОТКАЗЫВАЮТСЯ. В НИКАКОМ СЛУЧАЕ ВЛАДЕЛЕЦ АВТОРСКИХ ПРАВ ИЛИ СОТРУДНИКИ НЕ НЕСУТ ОТВЕТСТВЕННОСТИ ЗА ЛЮБЫЕ ПРЯМЫЕ, КОСВЕННЫЕ, СЛУЧАЙНЫЕ, СПЕЦИАЛЬНЫЕ, ШТРАФНЫЕ ИЛИ ПОСЛЕДОВАТЕЛЬНЫЕ УЩЕРБЫ (ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ИМИ, ПОЛУЧЕНИЕ ЗАМЕНЯЮЩИХ ТОВАРОВ ИЛИ УСЛУГ; ПОТЕРЯ ИСПОЛЬЗОВАНИЯ, ДАННЫХ ИЛИ ПРИБЫЛИ; ИЛИ ПЕРЕРЫВАНИЕ ДЕЯТЕЛЬНОСТИ), ПРИЧИНЕННЫЕ ИЗ-ЗА ЛЮБЫХ ПРИЧИН И ПО ЛЮБОЙ ТЕОРИИ ОТВЕТСТВЕННОСТИ, ЧТО ИМЕЕТ МЕСТО В ДОГОВОРЕ, СТРОГОЙ ОТВЕТСТВЕННОСТИ ИЛИ ДЕЛИКТЕ (ВКЛЮЧАЯ НЕБРЕЖНОСТЬ ИЛИ ДРУГИЕ), ВОЗНИКШИЕ ЛЮБЫМ ОБРАЗОМ ИЗ ИСПОЛЬЗОВАНИЯ ЭТОГО ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ, ДАЖЕ ЕСЛИ О НЕЙ БЫЛО ПРЕДУПРЕЖДЕНО.

Синтаксис и семантика регулярных выражений

Поскольку поддерживаемые этим модулем регулярные выражения очень обширны, читатель может обратиться к http://perldoc.perl.org/perlre.html для получения полной документации по регулярным выражениям Perl.

Поскольку обратный слэш \ является метасимволом как в языке программирования Nim, так и в регулярных выражениях, настоятельно рекомендуется использовать сырые строки Nim, чтобы обратные слэши интерпретировались движком регулярных выражений:

r"\S"  # matches any character that is not whitespace

Регулярное выражение — это шаблон, который сопоставляется с строкой-объектом слева направо. Большинство символов в шаблоне представляют собой сами себя и сопоставляются с соответствующими символами в объекте. В качестве тривиального примера шаблон:

The quick brown fox

сопоставляет часть строки-объекта, идентичную самой себе. Мощность регулярных выражений заключается в возможности включения альтернатив и повторений в шаблоне. Они кодируются в шаблоне с помощью метасимволов, которые не представляют сами себя, а интерпретируются каким-то специальным образом.

Существует два разных набора метасимволов: те, которые распознаются в любом месте шаблона, кроме квадратных скобок, и те, которые распознаются в квадратных скобках. За пределами квадратных скобок метасимволы таковы:

метасимвол значение
\ общий символ экранирования с несколькими применениями
^ утверждение начала строки (или строки, в режиме многострочности)
$ утверждение конца строки (или строки, в режиме многострочности)
. сопоставление любого символа, кроме новой строки (по умолчанию)
[ начало определения класса символов
| начало ветви альтернативы
( начало подшаблона
) конец подшаблона
{ начало квантификатора min/max
? расширяет значение (

также 0 или 1 квантификатор (равен {0,1})
также квантификатор минимизации

* квантификатор 0 или более (равен {0,})
+ квантификатор 1 или более (равен {1,})

также "поглощающий квантификатор"

Часть шаблона, которая находится в квадратных скобках, называется «классом символов». В классе символов единственными метасимволами являются:

метасимвол значение
\ общий символ экранирования
^ отмена класса, но только если это первый символ
- указывает диапазон символов
[ класс символов POSIX (только если за ним следует синтаксис POSIX)
] завершает класс символов

Следующие разделы описывают использование каждого метасимвола.

Обратный слэш

Символ обратного слэша имеет несколько применений. Во-первых, если за ним следует не буквенно-цифровой символ, он снимает любое специальное значение, которое может иметь этот символ. Это использование обратного слэша в качестве символа экранирования применяется как внутри, так и вне классов символов.

Например, если вы хотите сопоставить символ *, вы пишете \* в шаблоне. Это действие экранирования применяется независимо от того, интерпретируется ли последующий символ как метасимвол или нет, поэтому всегда безопасно предварять не буквенно-цифровой символ обратным слэшем, чтобы указать, что он представляет собой сам себя. В частности, если вы хотите сопоставить обратный слэш, вы пишете \\.

Непечатаемые символы

Второе использование обратного слэша обеспечивает способ кодирования непечатаемых символов в шаблонах в видимой форме. Не существует ограничений на появление непечатаемых символов, кроме двоичного нуля, который завершает шаблон, но когда шаблон готовится с помощью текстового редактора, обычно проще использовать одну из следующих последовательностей экранирования, чем двоичный символ, который она представляет::

символ значение
\a сигнал, то есть символ BEL (шестнадцатеричный 07)
\e escape (шестнадцатеричный 1B)
\f перевод страницы (шестнадцатеричный 0C)
\n новая строка (шестнадцатеричный 0A)
\r возврат каретки (шестнадцатеричный 0D)
\t табуляция (шестнадцатеричный 09)
\ddd символ с восьмеричным кодом ddd или обратная ссылка
\xhh символ с шестнадцатеричным кодом hh

После \x, считываются от нуля до двух шестнадцатеричных цифр (буквы могут быть в верхнем или нижнем регистре). В режиме UTF-8 любое количество шестнадцатеричных цифр может появиться между \x{ и }, но значение кода символа должно быть меньше 2**31 (то есть максимальное шестнадцатеричное значение — 7FFFFFFF). Если между \x{ и } появятся символы, отличные от шестнадцатеричных цифр, или если нет завершающего }, эта форма экранирования не распознается. Вместо этого начальный \x будет интерпретирован как базовый шестнадцатеричный escape, без последующих цифр, давая символ со значением ноль.

После \0 считываются до двух дополнительных восьмеричных цифр. В обоих случаях, если цифр меньше двух, используются только присутствующие. Таким образом, последовательность \0\x\07 определяет два двоичных нуля, за которыми следует символ BEL (значение кода 7). Убедитесь, что вы вводите две цифры после начального нуля, если символ шаблона, который следует за ним, сам по себе является восьмеричной цифрой.

Обработка обратного слэша, за которым следует цифра, отличная от 0, является сложной. Вне класса символов PCRE считывает её и любые последующие цифры как десятичное число. Если число меньше 10 или если было хотя бы столько же предыдущих открывающихся скобок в выражении, вся последовательность рассматривается как обратная ссылка. Описание того, как это работает, приведено позже, после обсуждения подшаблонов в скобках.

Внутри класса символов или если десятичное число больше 9 и не было столько же подшаблонов, PCRE повторно считывает до трёх восьмеричных цифр, следующих за обратным слэшем, и генерирует один байт из наименее значащих 8 бит значения. Любые последующие цифры представляют собой сами себя. Например:

пример значение
\040 ещё один способ записать пробел
\40 то же самое, при условии, что существует меньше 40 предыдущих подшаблонов
\7 всегда является обратной ссылкой
\11 может быть обратной ссылкой или другим способом записи табуляции
\011 всегда является табуляцией
\0113 табуляция, за которой следует символ "3"
\113 может быть обратной ссылкой, в противном случае символ с восьмеричным кодом 113
\377 может быть обратной ссылкой, в противном случае байт, состоящий целиком из 1-бит
\81 это либо обратная ссылка, либо двоичный ноль, за которым следуют два символа "8" и "1"

Обратите внимание, что восьмеричные значения 100 и выше не должны вводиться с ведущим нулём, поскольку никогда не считываются более трёх восьмеричных цифр.

Все последовательности, определяющие одно байтовое значение или один символ UTF-8 (в режиме UTF-8), могут использоваться как внутри, так и вне классов символов. Кроме того, внутри класса символов последовательность \b интерпретируется как символ удаления (шестнадцатеричный 08), а последовательность \X интерпретируется как символ "X". Вне класса символов эти последовательности имеют другие значения (см. ниже).

Общие типы символов

Третье использование обратного слэша заключается в определении общих типов символов. Следующие всегда распознаются:

Тип символа Значение
\d любая десятичная цифра
\D любой символ, который не является десятичной цифрой
\s любой пробельный символ
\S любой символ, который не является пробельным
\w любой символ "слова"
\W любой символ "не-слова"

Каждая пара последовательностей экранирования разделяет полный набор символов на два непересекающихся множества. Любой данный символ соответствует одному и только одному из каждой пары.

Эти последовательности типов символов могут появляться как внутри, так и вне классов символов. Они соответствуют одному символу соответствующего типа. Если текущая точка сопоставления находится в конце строки-предмета, все они терпят неудачу, так как нет символа для сопоставления.

Для совместимости с Perl, \s не соответствует символу VT (код 11). Это отличает его от класса "пробел" POSIX. Символами \s являются HT (9), LF (10), FF (12), CR (13) и пробел (32).

Символ "слова" — это нижнее подчеркивание или любой символ меньше 256, который является буквой или цифрой. Определение букв и цифр контролируется таблицами символов с низкими значениями PCRE и может меняться, если происходит сопоставление с учетом локального расположения (см. "Поддержка локального расположения" в странице pcreapi). Например, в локальном расположении "fr_FR" (французский) некоторые коды символов больше 128 используются для акцентированных букв, и эти буквы соответствуют \w.

В режиме UTF-8 символы со значениями больше 128 никогда не соответствуют \d, \s, или \w, и всегда соответствуют \D, \S, и \W. Это справедливо даже при наличии поддержки свойств символов Unicode.

Простые утверждения

Четвёртое использование обратной косой черты предназначено для определённых простых утверждений. Утверждение определяет условие, которое должно быть выполнено в определённой точке совпадения, без потребления каких-либо символов из строки-предмета. Использование подмасок для более сложных утверждений описано ниже. Утверждения с обратной косой чертой:

Утверждение Значение
\b соответствует границе слова
\B соответствует, когда нет границы слова
\A соответствует в начале строки-предмета
\Z соответствует в конце строки-предмета или перед символом новой строки в конце
\z соответствует в конце строки-предмета
\G соответствует первой позиции совпадения в строке-предмете

Эти утверждения не могут появляться в классах символов (но обратите внимание, что \b имеет другое значение, а именно символ обратного удаления, внутри класса символов).

Граница слова — это позиция в строке-предмете, где текущий символ и предыдущий символ оба не соответствуют \w или \W (т. е. один соответствует \w, а другой соответствует \W), или начало или конец строки, если первый или последний символ соответствует \w, соответственно.

Утверждения \A, \Z, и \z отличаются от традиционных знаков циркумфлекса и доллара тем, что они всегда соответствуют только самому началу и концу строки-предмета, независимо от установленных опций. Разница между \Z и \z заключается в том, что \Z соответствует символу новой строки, являющемуся последним символом строки, а также концу строки, в то время как \z соответствует только концу.

Пример:

## Unless specified otherwise, `start` parameter in each proc indicates
## where the scan starts, but outputs are relative to the start of the input
## string, not to `start`:
doAssert find("uxabc", re"(?<=x|y)ab", start = 1) == 2 # lookbehind assertion
doAssert find("uxabc", re"ab", start = 3) == -1 # we're past `start` => not found
doAssert not match("xabc", re"^abc$", start = 1)
  # can't match start of string since we're starting at 1

Импорты

pcre, strutils, rtarrays

Типы

RegexFlag = enum
  reIgnoreCase = 0,         ## do caseless matching
  reMultiLine = 1,          ## ``^`` and ``$`` match newlines within data
  reDotAll = 2,             ## ``.`` matches anything including NL
  reExtended = 3,           ## ignore whitespace and ``#`` comments
  reStudy = 4                ## study the expression (may be omitted if the
                             ## expression will be used only once)
параметры для регулярных выражений Исходный код Редактировать
Regex = ref RegexDesc
скомпилированное регулярное выражение Исходный код Редактировать
RegexError = object of ValueError
генерируется, если шаблон не является корректным регулярным выражением Исходный код Редактировать

Константы

MaxSubpatterns = 20
определяет максимальное количество подмасок, которые могут быть захвачены. Это ограничение по-прежнему действует для replacef и parallelReplace. Исходный код Редактировать

Процедуры

proc re(s: string; flags = {reStudy}): Regex {...}{.raises: [RegexError], tags: [].}

Конструктор для регулярных выражений.

Обратите внимание, что расширенные строковые литералы Nim поддерживают синтаксис re"[abc]" в качестве короткой формы для re(r"[abc]"). Также обратите внимание, что поскольку компиляция регулярного выражения является дорогостоящей операцией, следует избегать его непосредственного использования в аргументах функций, как показано в примерах ниже, если вы планируете использовать его многократно, так как это сильно скажется на производительности. (например, вне цикла, ...)

Исходный код Изменить
proc rex(s: string; flags = {reStudy, reExtended}): Regex {...}{.
    raises: [RegexError], tags: [].}

Конструктор для расширенных регулярных выражений.

Расширенные означают, что комментарии, начинающиеся с #, и пробелы игнорируются.

Исходный код Изменить
proc findBounds(buf: cstring; pattern: Regex; matches: var openArray[string];
                start = 0; bufSize: int): tuple[first, last: int] {...}{.raises: [],
    tags: [].}
возвращает начальную и конечную позиции pattern в buf (где buf имеет длину bufSize и не обязательно '\0' завершена), а также захваченные подстроки в массиве matches. Если совпадения нет, ничего не записывается в matches и возвращается (-1,0). Исходный код Изменить
proc findBounds(s: string; pattern: Regex; matches: var openArray[string];
                start = 0): tuple[first, last: int] {...}{.inline, raises: [],
    tags: [].}
возвращает начальную и конечную позиции pattern в s и захваченные подстроки в массиве matches. Если совпадения нет, ничего не записывается в matches и возвращается (-1,0). Исходный код Изменить
proc findBounds(buf: cstring; pattern: Regex;
                matches: var openArray[tuple[first, last: int]]; start = 0;
                bufSize = 0): tuple[first, last: int] {...}{.raises: [], tags: [].}
возвращает начальную и конечную позиции pattern в buf (где buf имеет длину bufSize и не обязательно '\0' завершена), а также захваченные подстроки в массиве matches. Если совпадения нет, ничего не записывается в matches и возвращается (-1,0). Исходный код Изменить
proc findBounds(s: string; pattern: Regex;
                matches: var openArray[tuple[first, last: int]]; start = 0): tuple[
    first, last: int] {...}{.inline, raises: [], tags: [].}
возвращает начальную и конечную позиции pattern в s и захваченные подстроки в массиве matches. Если совпадения нет, ничего не записывается в matches и возвращается (-1,0). Исходный код Изменить
proc findBounds(buf: cstring; pattern: Regex; start = 0; bufSize: int): tuple[
    first, last: int] {...}{.raises: [], tags: [].}
возвращает позицию first и last pattern в buf, где buf имеет длину bufSize (не обязательно '\0' завершена). Если совпадения нет, возвращается (-1,0). Исходный код Изменить
proc findBounds(s: string; pattern: Regex; start = 0): tuple[first, last: int] {...}{.
    inline, raises: [], tags: [].}

возвращает позицию first и last pattern в s. Если совпадения нет, возвращается (-1,0).

Примечание: есть улучшение скорости, если совпадения не нужно захватывать.

Пример:

assert findBounds("01234abc89", re"abc") == (5,7)
Исходный код Изменить
proc matchLen(s: string; pattern: Regex; matches: var openArray[string];
              start = 0): int {...}{.inline, raises: [], tags: [].}
то же, что и match, но возвращает длину совпадения, если совпадения нет, возвращается -1. Обратите внимание, что длина совпадения может быть нулевой. Исходный код Изменить
proc matchLen(buf: cstring; pattern: Regex; matches: var openArray[string];
              start = 0; bufSize: int): int {...}{.inline, raises: [], tags: [].}
то же, что и match, но возвращает длину совпадения, если совпадения нет, возвращается -1. Обратите внимание, что длина совпадения может быть нулевой. Исходный код Изменить
proc matchLen(s: string; pattern: Regex; start = 0): int {...}{.inline, raises: [],
    tags: [].}
то же, что и match, но возвращает длину совпадения, если совпадения нет, возвращается -1. Обратите внимание, что длина совпадения может быть нулевой.

Пример:

doAssert matchLen("abcdefg", re"cde", 2) == 3
doAssert matchLen("abcdefg", re"abcde") == 5
doAssert matchLen("abcdefg", re"cde") == -1
Исходный код Изменить
proc matchLen(buf: cstring; pattern: Regex; start = 0; bufSize: int): int {...}{.
    inline, raises: [], tags: [].}
то же, что и match, но возвращает длину совпадения, если совпадения нет, возвращается -1. Обратите внимание, что длина совпадения может быть нулевой. Исходный код Изменить
proc match(s: string; pattern: Regex; start = 0): bool {...}{.inline, raises: [],
    tags: [].}
возвращает true, если s[start..] соответствует pattern. Исходный код Изменить
proc match(s: string; pattern: Regex; matches: var openArray[string]; start = 0): bool {...}{.
    inline, raises: [], tags: [].}
возвращает true, если s[start..] соответствует pattern и захваченные подстроки в массиве matches. Если совпадения нет, ничего не записывается в matches и возвращается false.

Пример:

import sequtils
var matches: array[2, string]
if match("abcdefg", re"c(d)ef(g)", matches, 2):
  doAssert toSeq(matches) == @["d", "g"]
Исходный код Изменить
proc match(buf: cstring; pattern: Regex; matches: var openArray[string];
           start = 0; bufSize: int): bool {...}{.inline, raises: [], tags: [].}
возвращает true, если buf[start..<bufSize] соответствует pattern и захваченные подстроки в массиве matches. Если совпадения нет, ничего не записывается в matches и возвращается false. buf имеет длину bufSize (не обязательно '\0' завершена). Исходный код Изменить
proc find(buf: cstring; pattern: Regex; matches: var openArray[string];
          start = 0; bufSize = 0): int {...}{.raises: [], tags: [].}
возвращает начальную позицию pattern в buf и захваченные подстроки в массиве matches. Если совпадения нет, ничего не записывается в matches и возвращается -1. buf имеет длину bufSize (не обязательно '\0' завершена). Исходный код Изменить
proc find(s: string; pattern: Regex; matches: var openArray[string]; start = 0): int {...}{.
    inline, raises: [], tags: [].}
возвращает начальную позицию pattern в s и захваченные подстроки в массиве matches. Если совпадения нет, ничего не записывается в matches и возвращается -1. Исходный код Изменить
proc find(buf: cstring; pattern: Regex; start = 0; bufSize: int): int {...}{.
    raises: [], tags: [].}
возвращает начальную позицию pattern в buf, где buf имеет длину bufSize (не обязательно '\0' завершена). Если совпадения нет, возвращается -1. Исходный код Изменить
proc find(s: string; pattern: Regex; start = 0): int {...}{.inline, raises: [],
    tags: [].}
возвращает начальную позицию pattern в s. Если совпадения нет, возвращается -1. Поиск начинается с start.

Пример:

doAssert find("abcdefg", re"cde") == 2
doAssert find("abcdefg", re"abc") == 0
doAssert find("abcdefg", re"zz") == -1 # not found
doAssert find("abcdefg", re"cde", start = 2) == 2 # still 2
doAssert find("abcdefg", re"cde", start = 3) == -1 # we're past the start position
doAssert find("xabc", re"(?<=x|y)abc", start = 1) == 1
  # lookbehind assertion `(?<=x|y)` can look behind `start`
Исходный код Изменить
proc findAll(s: string; pattern: Regex; start = 0): seq[string] {...}{.inline,
    raises: [], tags: [].}
возвращает все совпадающие substrings s, которые соответствуют pattern. Если совпадения нет, возвращается @[]. Исходный код Изменить
proc contains(s: string; pattern: Regex; start = 0): bool {...}{.inline, raises: [],
    tags: [].}
то же, что и find(s, pattern, start) >= 0 Исходный код Изменить
proc contains(s: string; pattern: Regex; matches: var openArray[string];
              start = 0): bool {...}{.inline, raises: [], tags: [].}
то же, что и find(s, pattern, matches, start) >= 0 Исходный код Изменить
proc startsWith(s: string; prefix: Regex): bool {...}{.inline, raises: [], tags: [].}
возвращает true, если s начинается с шаблона prefix Исходный код Изменить
proc endsWith(s: string; suffix: Regex): bool {...}{.inline, raises: [], tags: [].}
возвращает true, если s оканчивается на шаблон suffix Исходный код Изменить
proc replace(s: string; sub: Regex; by = ""): string {...}{.raises: [], tags: [].}
Заменяет sub в s строкой by. В by доступ к группам захвата недоступен.

Пример:

doAssert "var1=key; var2=key2".replace(re"(\w+)=(\w+)") == "; "
doAssert "var1=key; var2=key2".replace(re"(\w+)=(\w+)", "?") == "?; ?"
Исходный код Изменить
proc replacef(s: string; sub: Regex; by: string): string {...}{.raises: [ValueError],
    tags: [].}
Заменяет sub в s строкой by. К группам захвата можно обратиться в by с помощью обозначения $i и $# (см. strutils.`%`).

Пример:

doAssert "var1=key; var2=key2".replacef(re"(\w+)=(\w+)", "$1<-$2$2") ==
  "var1<-keykey; var2<-key2key2"
Исходный код Изменить
proc multiReplace(s: string;
                  subs: openArray[tuple[pattern: Regex, repl: string]]): string {...}{.
    raises: [ValueError], tags: [].}
Возвращает изменённую копию s с параллельно применёнными подстановками из subs. Исходный код Изменить
proc transformFile(infile, outfile: string;
                   subs: openArray[tuple[pattern: Regex, repl: string]]) {...}{.
    raises: [IOError, ValueError], tags: [ReadIOEffect, WriteIOEffect].}
читает файл infile, выполняет параллельную замену (вызывает parallelReplace) и записывает результат в outfile. Вызывает IOError в случае ошибки. Предполагается использование для быстрой работы со скриптами. Исходный код Изменить
proc split(s: string; sep: Regex; maxsplit = -1): seq[string] {...}{.inline,
    raises: [], tags: [].}

Разделяет строку s на последовательность подстрок.

Часть, совпавшая с sep, не возвращается.

Исходный код Изменить
proc escapeRe(s: string): string {...}{.raises: [], tags: [].}
экранирует s для того, чтобы он был интерпретирован буквально при использовании в качестве регулярного выражения. Исходный код Изменить

Итераторы

iterator findAll(s: string; pattern: Regex; start = 0): string {...}{.raises: [],
    tags: [].}

Возвращает все совпадающие подстроки в s, которые соответствуют pattern.

Обратите внимание, что, поскольку это итератор, вы не должны изменять строку, по которой вы итерируетесь: могут произойти нежелательные последствия.

Исходный код Изменить
iterator findAll(buf: cstring; pattern: Regex; start = 0; bufSize: int): string {...}{.
    raises: [], tags: [].}

Возвращает все совпадающие substrings в s, которые соответствуют pattern.

Обратите внимание, что, поскольку это итератор, вы не должны изменять строку, по которой вы итерируетесь: могут произойти нежелательные последствия.

Исходный код Изменить
iterator split(s: string; sep: Regex; maxsplit = -1): string {...}{.raises: [],
    tags: [].}

Разделяет строку s на подстроки.

Подстроки разделены регулярным выражением sep (и часть, совпавшая с sep, не возвращается).

Пример:

import sequtils
doAssert toSeq(split("00232this02939is39an22example111", re"\d+")) ==
  @["", "this", "is", "an", "example", ""]
Исходный код Изменить

Шаблоны

template `=~`(s: string; pattern: Regex): untyped
Это вызов match с неявным объявленным массивом matches, который можно использовать в области видимости вызова =~:

Пример:

proc parse(line: string): string =
  if line =~ re"\s*(\w+)\s*\=\s*(\w+)": # matches a key=value pair:
    result = $(matches[0], matches[1])
  elif line =~ re"\s*(\#.*)": # matches a comment
    # note that the implicit ``matches`` array is different from 1st branch
    result = $(matches[0],)
  else: doAssert false
  doAssert not declared(matches)
doAssert parse("NAME = LENA") == """("NAME", "LENA")"""
doAssert parse("   # comment ... ") == """("# comment ... ",)"""
Исходный код Изменить

© 2006–2021 Andreas Rumpf
Licensed under the MIT License.
https://nim-lang.org/docs/re.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API