Spec-Zone.ru › Nim

std/re

Исходный кодРедактировать

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

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

Примечание: Также существуют альтернативные пакеты Nim, такие как tinyre и regex.

Лицензия PCRE:

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

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

Автор: Филип Хэйзел
Copyright (c) 1997-2005 University of Cambridge


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

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

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

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

Поскольку поддерживаемые этим модулем регулярные выражения очень обширны, читатель может обратиться к 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 будет интерпретироваться как основное шестнадцатеричное экранирование без последующих цифр, давая символ со значением ноль.

После \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 интерпретируется как символ backspace (шестнадцатеричный 08), а последовательность \X интерпретируется как символ «X». Вне класса символов эти последовательности имеют другое значение (см. ниже).

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

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

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

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

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

Для совместимости с 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 соответствует только концу.

Пример:

import std/re
## 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

Типы

Regex = ref RegexDesc
скомпилированное регулярное выражение Исходный код Изменить
RegexError = object of ValueError
генерируется, если шаблон не является допустимым регулярным выражением. Исходный код Изменить
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)
параметры для регулярных выражений Исходный код Изменить

Константы

MaxReBufSize = 2147483647'i32
Максимальный буфер PCRE (API 1) начальный/размер равный high(cint), который даже для 64-битных систем может быть либо 231-1, либо 263-1. Исходный код Изменить
MaxSubpatterns = 20
определяет максимальное количество подвыражений, которые могут быть захвачены. Этот предел все еще существует для replacef и parallelReplace Исходный код Изменить

Процедуры

proc contains(s: string; pattern: Regex; matches: var openArray[string];
              start = 0): bool {.inline, ...raises: [], tags: [], forbids: [].}
совпадает с find(s, pattern, matches, start) >= 0
Примечание: Память для matches должна быть выделена перед вызовом этой функции, иначе она останется пустой.
Исходный код Изменить
proc contains(s: string; pattern: Regex; start = 0): bool {.inline, ...raises: [],
    tags: [], forbids: [].}
совпадает с find(s, pattern, start) >= 0 Исходный код Изменить
proc endsWith(s: string; suffix: Regex): bool {.inline, ...raises: [], tags: [],
    forbids: [].}
возвращает true, если s оканчивается на шаблон suffix Исходный код Изменить
proc escapeRe(s: string): string {....raises: [], tags: [], forbids: [].}
экранирует s, чтобы он соответствовал точному тексту при использовании в качестве регулярного выражения. Исходный код Изменить
proc find(buf: cstring; pattern: Regex; matches: var openArray[string];
          start = 0; bufSize: int): int {....raises: [], tags: [], forbids: [].}
возвращает начальную позицию pattern в buf и захваченные подстроки в массиве matches. Если совпадение не найдено, в matches ничего не записывается, и возвращается -1. buf имеет длину bufSize (не обязательно завершается нулем).
Примечание: Память для matches должна быть выделена перед вызовом этой функции, иначе она останется пустой.
Исходный код Изменить
proc find(buf: cstring; pattern: Regex; start = 0; bufSize: int): int {.
    ...raises: [], tags: [], forbids: [].}
возвращает начальную позицию pattern в buf, где buf имеет длину bufSize (не обязательно завершается нулем). Если совпадение не найдено, возвращается -1. Исходный код Изменить
proc find(s: string; pattern: Regex; matches: var openArray[string]; start = 0): int {.
    inline, ...raises: [], tags: [], forbids: [].}
возвращает начальную позицию pattern в s и захваченные подстроки в массиве matches. Если совпадение не найдено, в matches ничего не записывается, и возвращается -1.
Примечание: Память для matches должна быть выделена перед вызовом этой функции, иначе она останется пустой.
Исходный код Изменить
proc find(s: string; pattern: Regex; start = 0): int {.inline, ...raises: [],
    tags: [], forbids: [].}
возвращает начальную позицию 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: [], forbids: [].}
возвращает все совпадения substrings из s, которые соответствуют pattern. Если совпадение не найдено, возвращается @[]. Исходный код Изменить
proc findBounds(buf: cstring; pattern: Regex;
                matches: var openArray[tuple[first, last: int]]; start = 0;
                bufSize: int): tuple[first, last: int] {....raises: [], tags: [],
    forbids: [].}
возвращает начальную и конечную позиции pattern в buf (где buf имеет длину bufSize и не обязательно завершается нулем), а также захваченные подстроки в массиве matches. Если совпадение не найдено, в matches ничего не записывается, и возвращается (-1,0).
Примечание: Память для matches должна быть выделена перед вызовом этой функции, иначе она останется пустой.
Исходный код Изменить
proc findBounds(buf: cstring; pattern: Regex; matches: var openArray[string];
                start = 0; bufSize: int): tuple[first, last: int] {....raises: [],
    tags: [], forbids: [].}

возвращает начальную и конечную позиции pattern в buf (где buf имеет длину bufSize и не обязательно завершается нулем), а также захваченные подстроки в массиве matches. Если совпадение не найдено, в matches ничего не записывается, и возвращается (-1,0).

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

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

Пример:

var matches = newSeq[tuple[first, last: int]](1)
let (first, last) = findBounds("Hello World", re"(\w+)", matches)
doAssert first == 0
doAssert last == 4
doAssert matches[0] == (0, 4)
Исходный код Изменить
proc findBounds(s: string; pattern: Regex; matches: var openArray[string];
                start = 0): tuple[first, last: int] {.inline, ...raises: [],
    tags: [], forbids: [].}
возвращает начальную и конечную позиции pattern в s и захваченные подстроки в массиве matches. Если совпадение не найдено, в matches ничего не записывается, и возвращается (-1,0).
Примечание: Память для matches должна быть выделена перед вызовом этой функции, иначе она останется пустой.

Пример:

var matches = newSeq[string](1)
let (first, last) = findBounds("Hello World", re"(W\w+)", matches)
doAssert first == 6
doAssert last == 10
doAssert matches[0] == "World"
Исходный код Изменить
proc findBounds(s: string; pattern: Regex; start = 0): tuple[first, last: int] {.
    inline, ...raises: [], tags: [], forbids: [].}

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

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

Пример:

assert findBounds("01234abc89", re"abc") == (5,7)
Исходный код Изменить
proc match(buf: cstring; pattern: Regex; matches: var openArray[string];
           start = 0; bufSize: int): bool {.inline, ...raises: [], tags: [],
    forbids: [].}
возвращает true если buf[start..<bufSize] соответствует pattern и захваченные подстроки в массиве matches. Если не соответствует, ничего не записывается в matches и возвращается false. buf имеет длину bufSize (не обязательно '\0'-завершённая).
Примечание: Память для matches должна быть выделена перед вызовом этой функции, в противном случае она останется пустой.
Исходный код Редактировать
proc match(s: string; pattern: Regex; matches: var openArray[string]; start = 0): bool {.
    inline, ...raises: [], tags: [], forbids: [].}
возвращает true если s[start..] соответствует pattern и захваченные подстроки в массиве matches. Если не соответствует, ничего не записывается в matches и возвращается false.
Примечание: Память для matches должна быть выделена перед вызовом этой функции, в противном случае она останется пустой.

Пример:

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

Пример:

doAssert matchLen("abcdefg", re"cde", 2) == 3
doAssert matchLen("abcdefg", re"abcde") == 5
doAssert matchLen("abcdefg", re"cde") == -1
Исходный код Редактировать
proc multiReplace(s: string;
                  subs: openArray[tuple[pattern: Regex, repl: string]]): string {.
    ...raises: [ValueError], tags: [], forbids: [].}
Возвращает измененную копию s с выполненными заменами из subs параллельно. Исходный код Редактировать
proc re(s: string; flags = {reStudy}): Regex {....raises: [RegexError], tags: [],
    forbids: [].}

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

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

Исходный код Редактировать
proc replace(s: string; sub: Regex; by = ""): string {....raises: [], tags: [],
    forbids: [].}
Заменяет 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: [], forbids: [].}
Заменяет sub в s строкой by. Захваты могут быть доступны в by с помощью обозначения $i и $# (см. strutils.`%`).

Пример:

doAssert "var1=key; var2=key2".replacef(re"(\w+)=(\w+)", "$1<-$2$2") ==
  "var1<-keykey; var2<-key2key2"
Исходный код Редактировать
proc rex(s: string; flags = {reStudy, reExtended}): Regex {.
    ...raises: [RegexError], tags: [], forbids: [].}

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

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

Исходный код Редактировать
proc split(s: string; sep: Regex; maxsplit = -1): seq[string] {.inline,
    ...raises: [], tags: [], forbids: [].}

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

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

Исходный код Редактировать
proc startsWith(s: string; prefix: Regex): bool {.inline, ...raises: [], tags: [],
    forbids: [].}
возвращает true, если s начинается с шаблона prefix Исходный код Редактировать
proc transformFile(infile, outfile: string;
                   subs: openArray[tuple[pattern: Regex, repl: string]]) {.
    ...raises: [IOError, ValueError], tags: [ReadIOEffect, WriteIOEffect],
    forbids: [].}
считывает файл infile, выполняет параллельную замену (вызывает parallelReplace) и записывает обратно в outfile. Вызывает IOError если возникла ошибка. Предполагается, что это используется для быстрой разработки сценариев. Исходный код Редактировать

Итераторы

iterator findAll(buf: cstring; pattern: Regex; start = 0; bufSize: int): string {.
    ...raises: [], tags: [], forbids: [].}

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

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

Исходный код Редактировать
iterator findAll(s: string; pattern: Regex; start = 0): string {....raises: [],
    tags: [], forbids: [].}

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

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

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

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

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

Пример:

import std/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: raiseAssert "unreachable"
  doAssert not declared(matches)
doAssert parse("NAME = LENA") == """("NAME", "LENA")"""
doAssert parse("   # comment ... ") == """("# comment ... ",)"""
Исходный код Редактировать

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

Spec-Zone.ru

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