std/nre
ИсточникРедактироватьЧто такое NRE?
Библиотека регулярных выражений для Nim, использующая PCRE для сложной работы.
Для документации по написанию шаблонов существует официальная документация PCRE по шаблонам. Вы также можете найти множество сторонних документаций и инструментов в интернете.
sequtils.toSeq, у нас плохие новости для вас. Эта библиотека не работает с ним из-за документированных ограничений компилятора. В качестве обходного решения используйте это:Пример:
import std/nre # either `import std/nre except toSeq` or fully qualify `sequtils.toSeq`: import std/sequtils iterator iota(n: int): int = for i in 0..<n: yield i assert sequtils.toSeq(iota(3)) == @[0, 1, 2]
Лицензирование
PCRE имеет дополнительные условия, с которыми вы должны согласиться для использования этого модуля.
Пример:
import std/nre
import std/sugar
let vowels = re"[aeoui]"
let bounds = collect:
for match in "moiga".findIter(vowels): match.matchBounds
assert bounds == @[1 .. 1, 2 .. 2, 4 .. 4]
from std/sequtils import toSeq
let s = sequtils.toSeq("moiga".findIter(vowels))
# fully qualified to avoid confusion with nre.toSeq
assert s.len == 3
let firstVowel = "foo".find(vowels)
let hasVowel = firstVowel.isSome()
assert hasVowel
let matchBounds = firstVowel.get().captureBounds[-1]
assert matchBounds.a == 1
# as with module `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`:
assert find("uxabc", re"(?<=x|y)ab", start = 1).get.captures[-1] == "ab"
assert find("uxabc", re"ab", start = 3).isNone Импорты
- pcre, util, таблицы, strutils, options, unicode
Типы
CaptureBounds = distinct RegexMatch
- Источник Редактировать
Captures = distinct RegexMatch
- Источник Редактировать
InvalidUnicodeError = ref object of RegexError pos*: int ## the location of the invalid unicode in bytes
- Выбрасывается при неудачном сопоставлении из-за некорректного Unicode в строках Источник Редактировать
Regex = ref object pattern*: string ## not nil ## nil
- Представляет шаблон, к которому применяются сопоставления, созданный с помощью
re(string). Примеры:re"foo",re(r"(*ANYCRLF)(?x)foo # comment"..pattern: string- строка, используемая для создания шаблона. Подробности о том, как написать шаблон, см. в официальной документации PCRE по шаблонам.
captureCount: int- количество захватов, содержащихся в шаблоне.
captureNameId: Table[string, int]- таблица, сопоставляющая имена захватов с их числовыми идентификаторами.
Параметры
Следующие параметры могут появляться где угодно в шаблоне и влияют на остальную часть шаблона.
-
(?i)- регистронезависимый -
(?m)- многострочный:^и$соответствуют началу и концу строк, а не всей строки-предмета -
(?s)-.также соответствует переводу строки (dotall) -
(?U)- выражения по умолчанию не жадные.?можно добавить к квалификатору, чтобы сделать его жадным -
(?x)- пробелы и комментарии (#) игнорируются (extended) -
(?X)- символьные экранирования без специального значения (\wпротив\a) считаются ошибками (extra)
Один или несколько из этих параметров могут появиться только в начале шаблона:
-
(*UTF8)- обрабатывать и шаблон, и строку-предмет как UTF-8 -
(*UCP)- свойства Unicode-символов;\wсоответствуетя -
(*U)- комбинация двух вышеперечисленных параметров -
(*FIRSTLINE*)- завершается неудачей, если нет совпадения на первой строке -
(*NO_AUTO_CAPTURE)- отключает автоматический захват для групп;(?<name>...)можно использовать для захвата -
(*CR)- переводы строк разделены\r -
(*LF)- переводы строк разделены\n(по умолчанию для UNIX) -
(*CRLF)- переводы строк разделены\r\n(по умолчанию для Windows) -
(*ANYCRLF)- переводы строк разделены любым из вышеперечисленных -
(*ANY)- переводы строк разделены любым из вышеперечисленных и Unicode-переводами строк:отдельные символы VT (вертикальная табуляция, U+000B), FF (перевод страницы, U+000C), NEL (следующая строка, U+0085), LS (разделитель строк, U+2028) и PS (разделитель абзацев, U+2029). Для 8-битной библиотеки два последних распознаются только в режиме UTF-8. — man pcre
-
(*JAVASCRIPT_COMPAT)- совместимость с JavaScript -
(*NO_STUDY)- отключение изучения; изучение включено по умолчанию
Для получения более подробной информации о группах параметров, см. разделы Установка параметров и Конвенция перевода строк в руководстве по синтаксису PCRE.
Некоторые из этих параметров не являются частью PCRE и преобразуются nre в флаги PCRE. К ним относятся
Источник РедактироватьNEVER_UTF,ANCHORED,DOLLAR_ENDONLY,FIRSTLINE,NO_AUTO_CAPTURE,JAVASCRIPT_COMPAT,U,NO_STUDY. В других обёртках PCRE вам нужно будет передавать их как отдельные флаги в PCRE. RegexError = ref object of CatchableError
- Источник Редактировать
RegexInternalError = ref object of RegexError
- Внутренняя ошибка модуля, вероятно, указывает на ошибку Источник Редактировать
RegexMatch = object pattern*: Regex ## The regex doing the matching. ## Not nil. str*: string ## The string that was matched against. ## First item is the bounds of the match ## Other items are the captures ## `a` is inclusive start, `b` is exclusive end- Обычно виден как OptionRegexMatch, он представляет результат выполнения. При неудаче — none, при успехе — some.
pattern: Regex- шаблон, который сопоставляется
str: string- строка, с которой производилось сопоставление
captures[]: string- строковое значение того, что было захвачено под этим идентификатором. Если значение некорректно, поведение неопределено. Если идентификатор равен
-1, возвращается всё совпадение. Если данное захват не был сопоставлен, возвращаетсяnil. См. примеры дляmatch. captureBounds[]: HSlice[int, int]- получает границы заданного захвата в соответствии с теми же правилами, что и выше. Если захват не заполнен, возвращается
None. Границы являются включительными. См. примеры дляmatch. match: string- полный текст совпадения.
matchBounds: HSlice[int, int]- границы совпадения, как и в
captureBounds[] (captureBounds|captures).toTable- возвращает таблицу с каждым именованным захватом в качестве ключа.
(captureBounds|captures).toSeq- возвращает все захваты по их номеру.
$: string- то же, что и
match
StudyError = ref object of RegexError
- Выбрасывается, когда изучение регулярного выражения терпит неудачу по какой-либо причине. Сообщение содержит код ошибки. Источник Редактировать
SyntaxError = ref object of RegexError pos*: int ## the location of the syntax error in bytes pattern*: string ## the pattern that caused the problem
- Выбрасывается при синтаксической ошибке в строке регулярного выражения, переданной в Источник Редактировать
Процедуры
proc `$`(pattern: RegexMatch): string {....raises: [], tags: [], forbids: [].}- Исходный код Редактировать
proc `==`(a, b: Regex): bool {....raises: [], tags: [], forbids: [].}- Исходный код Редактировать
proc `==`(a, b: RegexMatch): bool {....raises: [], tags: [], forbids: [].}- Исходный код Редактировать
func `[]`(pattern: CaptureBounds; i: int): HSlice[int, int] {....raises: [], tags: [], forbids: [].}- Исходный код Редактировать
func `[]`(pattern: CaptureBounds; name: string): HSlice[int, int] {. ...raises: [KeyError], tags: [], forbids: [].}- Исходный код Редактировать
func `[]`(pattern: Captures; i: int): string {....raises: [], tags: [], forbids: [].}- Исходный код Редактировать
func `[]`(pattern: Captures; name: string): string {....raises: [KeyError], tags: [], forbids: [].}- Исходный код Редактировать
func captureBounds(pattern: RegexMatch): CaptureBounds {....raises: [], tags: [], forbids: [].}- Исходный код Редактировать
proc captureCount(pattern: Regex): int {....raises: [ValueError], tags: [], forbids: [].}- Исходный код Редактировать
proc captureNameId(pattern: Regex): Table[string, int] {....raises: [], tags: [], forbids: [].}- Исходный код Редактировать
func captures(pattern: RegexMatch): Captures {....raises: [], tags: [], forbids: [].}- Исходный код Редактировать
func contains(pattern: CaptureBounds; i: int): bool {....raises: [], tags: [], forbids: [].}- Исходный код Редактировать
func contains(pattern: CaptureBounds; name: string): bool {....raises: [KeyError], tags: [], forbids: [].}- Исходный код Редактировать
func contains(pattern: Captures; i: int): bool {....raises: [], tags: [], forbids: [].}- Исходный код Редактировать
func contains(pattern: Captures; name: string): bool {....raises: [KeyError], tags: [], forbids: [].}- Исходный код Редактировать
proc contains(str: string; pattern: Regex; start = 0; endpos = int.high): bool {. ...raises: [ValueError, RegexInternalError, InvalidUnicodeError], tags: [], forbids: [].}- Определить, содержит ли строка заданный шаблон между конечными и начальными позициями: Эта функция эквивалентна
isSome(str.find(pattern, start, endpos)).Пример:
assert "abc".contains(re"bc") assert not "abc".contains(re"cd") assert not "abc".contains(re"a", start = 1)
Исходный код Редактировать proc escapeRe(str: string): string {....gcsafe, raises: [], tags: [], forbids: [].}-
Экранирует строку, чтобы она не соответствовала никаким специальным символам. Несовместимо с флагом Extra (
X).Экранированный символ:
\ + * ? [ ^ ] $ ( ) { } = ! < > | : -Пример:
assert escapeRe("fly+wind") == "fly\\+wind" assert escapeRe("!") == "\\!" assert escapeRe("nim*") == "nim\\*"Исходный код Редактировать proc find(str: string; pattern: Regex; start = 0; endpos = int.high): Option[ RegexMatch] {....raises: [ValueError, RegexInternalError, InvalidUnicodeError], tags: [], forbids: [].}- Ищет заданный шаблон в строке между конечными и начальными позициями.
start- Начальная точка для начала сопоставления.
|abcэто0;a|bcэто1 endpos- Максимальный индекс для сопоставления;
int.highозначает конец строки, в противном случае это включительная верхняя граница.
proc findAll(str: string; pattern: Regex; start = 0; endpos = int.high): seq[ string] {....raises: [ValueError, RegexInternalError, InvalidUnicodeError], tags: [], forbids: [].}- Исходный код Редактировать
func match(pattern: RegexMatch): string {....raises: [], tags: [], forbids: [].}- Исходный код Редактировать
proc match(str: string; pattern: Regex; start = 0; endpos = int.high): Option[ RegexMatch] {....raises: [ValueError, RegexInternalError, InvalidUnicodeError], tags: [], forbids: [].}- Подобно find(...), но закреплено в начале строки.
Пример:
assert "foo".match(re"f").isSome assert "foo".match(re"o").isNone assert "abc".match(re"(\w)").get.captures[0] == "a" assert "abc".match(re"(?<letter>\w)").get.captures["letter"] == "a" assert "abc".match(re"(\w)\w").get.captures[-1] == "ab" assert "abc".match(re"(\w)").get.captureBounds[0] == 0 .. 0 assert 0 in "abc".match(re"(\w)").get.captureBounds assert "abc".match(re"").get.captureBounds[-1] == 0 .. -1 assert "abc".match(re"abc").get.captureBounds[-1] == 0 .. 2
Исходный код Редактировать func matchBounds(pattern: RegexMatch): HSlice[int, int] {....raises: [], tags: [], forbids: [].}- Исходный код Редактировать
proc re(pattern: string): Regex {....raises: [KeyError, SyntaxError, StudyError, ValueError], tags: [], forbids: [].}- Исходный код Редактировать
proc replace(str: string; pattern: Regex; sub: string): string {. ...raises: [ValueError, RegexInternalError, InvalidUnicodeError, KeyError], tags: [], forbids: [].}- Исходный код Редактировать
proc replace(str: string; pattern: Regex; subproc: proc (match: RegexMatch): string): string {. ...raises: [ValueError, RegexInternalError, InvalidUnicodeError, Exception], tags: [RootEffect], forbids: [].}-
Заменяет каждый совпадение Regex в строке на
subproc, которое никогда не должно быть или возвращатьnil.Если
subprocявляется процедуройproc (RegexMatch): string, то она выполняется с каждым совпадением, а возвращаемое значение является значением замены.Если
subprocявляется процедуройproc (string): string, то она выполняется со всем текстом совпадения, а возвращаемое значение является значением замены.Если
subprocявляется строкой, синтаксис следующий:-
$$- буквальное значение$ -
$123- номер захвата123 -
$foo- именованный захватfoo -
${foo}- то же самое, что выше -
$1$#- первый и второй захваты -
$#- первый захват -
$0- полное совпадение
Если указанный захват отсутствует, выбрасывается исключение
Исходный код РедактироватьIndexDefectдля неуказанных захватов иKeyErrorдля именованных захватов. -
proc replace(str: string; pattern: Regex; subproc: proc (match: string): string): string {. ...raises: [ValueError, RegexInternalError, InvalidUnicodeError, Exception], tags: [RootEffect], forbids: [].}- Исходный код Редактировать
proc split(str: string; pattern: Regex; maxSplit = -1; start = 0): seq[string] {. ...raises: [ValueError, RegexInternalError, InvalidUnicodeError], tags: [], forbids: [].}-
Разделяет строку с помощью заданного регулярного выражения. Это работает в соответствии с правилами, используемыми Perl и Javascript.
startведет себя так же, как в find(...).Пример:
# - If the match is zero-width, then the string is still split: assert "123".split(re"") == @["1", "2", "3"] # - If the pattern has a capture in it, it is added after the string # split: assert "12".split(re"(\d)") == @["", "1", "", "2", ""] # - If `maxsplit != -1`, then the string will only be split # `maxsplit - 1` times. This means that there will be `maxsplit` # strings in the output seq. assert "1.2.3".split(re"\.", maxsplit = 2) == @["1", "2.3"]
Исходный код Редактировать proc toSeq(pattern: CaptureBounds; default = none(HSlice[int, int])): seq[ Option[HSlice[int, int]]] {....raises: [ValueError], tags: [], forbids: [].}- Исходный код Редактировать
proc toSeq(pattern: Captures; default: Option[string] = none(string)): seq[ Option[string]] {....raises: [ValueError], tags: [], forbids: [].}- Исходный код Редактировать
func toTable(pattern: CaptureBounds): Table[string, HSlice[int, int]] {. ...raises: [KeyError], tags: [], forbids: [].}- Исходный код Редактировать
func toTable(pattern: Captures): Table[string, string] {....raises: [KeyError], tags: [], forbids: [].}- Исходный код Редактировать
Итераторы
iterator findIter(str: string; pattern: Regex; start = 0; endpos = int.high): RegexMatch {. ...raises: [ValueError, RegexInternalError, InvalidUnicodeError], tags: [], forbids: [].}- Работает так же, как find(...), но находит все неперекрывающиеся совпадения:
Пример:
import std/sugar assert collect(for a in "2222".findIter(re"22"): a.match) == @["22", "22"] # not @["22", "22", "22"]
Аргументы такие же, как у find(...)
Варианты:
-
proc findAll(...)возвращаетseq[string]
-
iterator items(pattern: CaptureBounds; default = none(HSlice[int, int])): Option[ HSlice[int, int]] {....raises: [ValueError], tags: [], forbids: [].}- Исходный код Редактировать
iterator items(pattern: Captures; default: Option[string] = none(string)): Option[ string] {....raises: [ValueError], tags: [], forbids: [].}- Исходный код Редактировать
© 2006–2024 Andreas Rumpf
Licensed under the MIT License.
https://nim-lang.org/docs/nre.html