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

Grouping and Capturing

Place parentheses around multiple tokens to group them together. You can then apply a quantifier to the group. E.g. Set(Value)? matches Set or SetValue.

Parentheses create a capturing group. The above example has one group. After the match, group number one contains nothing if Set was matched. It contains Value if SetValue was matched. How to access the group’s contents depends on the software or programming language you’re using. Group zero always contains the entire regex match.

Use the special syntax Set(?:Value)? to group tokens without creating a capturing group. This is more efficient if you don’t plan to use the group’s contents. Do not confuse the question mark in the non-capturing group syntax with the quantifier.

Разбить число на разряды

Задача: Разбить число на разряды например запятыми. Формально задача выглядит так «вставить запятые во всех позициях, у которых количество цифр справа кратно трем, а слева есть хотя бы одна цифра»

Второе требование выполняется при помощи ретроспективной проверки. Одной цифры слева достаточно для выполнения этого требования, а этот критерий задается выражением (?⇐\d).

Группа из трех цифр определяется выражением \d\d\d. Заключим ее в конструкцию (…)+, чтобы совпадение могло состоять из нескольких групп, и завершим метасимволом $, чтобы гарантировать отсутствие символов после совпадения. Само по себе выражение (\d\d\d)+$ совпадает с группами из трех цифр, следующими до конца строки, но в конструкции опережающей проверки (?=…) оно совпадает с позицией, справа от которой до конца строки следуют группы из трех цифр. Однако перед первой цифрой запятая не ставится, поэтому совпадение дополнительно ограничивается ретроспективной проверкой (?⇐\d).

Чтобы выражение стало более эффективным можно добавить несохраняющие скобки ?: в (?:\d\d\d), в этом случае подсистема регулярных выражений не будет тратить ресурсы на сохранение текста в круглых скобках.

Реализация PHP (PCRE библиотека регулярных выражений):<?php $n = «7500400300222»;

//$n = preg_replace(‘/(?<=\d)(?=(\d\d\d)+$)/’, ‘,’, $n);
$n = preg_replace(‘/(?<=\d)(?=(?:\d\d\d)+$)/’, ‘,’, $n);
echo «$n\n»;
?>

Ссылки

  • Джеффри Фридл — «Регулярные выражения» 3-е издание ISBN-13: 978-5-93286-121-9 ISBN-10: 5-93286-121-5
  • Библиотека регулярных выражений

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

История

Истоки регулярных выражений лежат в теории автоматов, теории формальных языков и классификации формальных грамматик по Хомскому.

Эти области изучают вычислительные модели (автоматы) и способы описания и классификации формальных языков.
В 1940-х гг. Уоррен Маккалок и Уолтер Питтс описали нейронную систему, используя простой автомат в качестве модели нейрона.

Математик Стивен Клини позже описал эти модели, используя свою систему математических обозначений, названную «регулярные множества».

Кен Томпсон встроил их в редактор QED, а затем в редактор ed под UNIX.
С этого времени регулярные выражения стали широко использоваться в UNIX и UNIX-подобных утилитах, например в expr, awk, Emacs, vi, lex и Perl.

Регулярные выражения в Perl и Tcl происходят от реализации, написанной Генри Спенсером.
Филип Хейзел разработал библиотеку PCRE (англ. Perl-compatible regular expressions — Perl-совместимые регулярные выражения), которая используется во многих современных инструментах, таких как PHP и Apache.

Repetition

You can control how many times a pattern matches with the repetition operators:

  • : 0 or 1.
  • : 1 or more.
  • : 0 or more.

Note that the precedence of these operators is high, so you can write: to match either American or British spellings. That means most uses will need parentheses, like .

You can also specify the number of matches precisely:

  • : exactly n
  • : n or more
  • : between n and m

By default these matches are “greedy”: they will match the longest string possible. You can make them “lazy”, matching the shortest string possible by putting a after them:

  • : 0 or 1, prefer 0.
  • : 1 or more, match as few times as possible.
  • : 0 or more, match as few times as possible.
  • : n or more, match as few times as possible.
  • : between n and m, , match as few times as possible, but at least n.

You can also make the matches possessive by putting a after them, which means that if later parts of the match fail, the repetition will not be re-tried with a smaller number of characters. This is an advanced feature used to improve performance in worst-case scenarios (called “catastrophic backtracking”).

  • : 0 or 1, possessive.
  • : 1 or more, possessive.
  • : 0 or more, possessive.
  • : exactly n, possessive.
  • : n or more, possessive.
  • : between n and m, possessive.

A related concept is the atomic-match parenthesis, . If a later match fails and the engine needs to back-track, an atomic match is kept as is: it succeeds or fails as a whole. Compare the following two regular expressions:

Non-Printable Characters

You can use special character sequences to put non-printable characters in your regular expression. Use \t to match a tab character (ASCII 0x09), \r for carriage return (0x0D) and \n for line feed (0x0A). More exotic non-printables are \a (bell, 0x07), \e (escape, 0x1B), \f (form feed, 0x0C) and \v (vertical tab, 0x0B). Remember that Windows text files use \r\n to terminate lines, while UNIX text files use \n.

If your application supports Unicode, use \uFFFF or \x{FFFF} to insert a Unicode character. \u20AC or \x{20AC} matches the euro currency sign.

If your application does not support Unicode, use \xFF to match a specific character by its hexadecimal index in the character set. \xA9 matches the copyright symbol in the Latin-1 character set.

All non-printable characters can be used directly in the regular expression, or as part of a character class.

Unicode. Алфавиты и блоки: \р, \Р

Свойства Unicode, алфавиты и блоки: \р{свойство}, \Р{свойство}. На концептуальном уровне Юникод представляет собой отображение множества символов на множество кодов, но стандарт Юникода не сводится к простому перечислению пар. Он также определяет атрибуты символов (например, «этот символ является строчной буквой», «этот символ пишется справа налево», «этот символ является диакритическим знаком, который должен объединяться с другим символом» и т. д.).
Уровень поддержки этих атрибутов зависит от конкретной программы, но многие программы с поддержкой Юникода позволяют находить хотя бы некоторые из них при помощи конструкций \p{атрибут} (символ, обладающий указанным атрибутом) и \P{атрибут} (символ, не обладающий атрибутом).

Оптимизация RegExp

Рекомендации по оптимизации регулярных выражений.

  • Ускоренное достижение совпадения. Руководствуясь знаниями принципов работы традиционного механизма НКА, можно привести механизм к совпадению по ускоренному пути. Рассмотрим пример  this|that. Каждая альтернатива начинается с th, если у первой альтернативы не найдется совпадение для th, то th второй альтернативы тоже заведомо не совпадет, поэтому такая попытка заведомо завершится неудачей. Чтобы время не тратилось даром, можно сформулировать то же выражение в виде th(?:is|at). В этом случае th проверяется всего один раз, а относительно затратная конструкция выбора откладывается до момента, когда она становится действительно необходимой. Кроме того, в выражении th(?:is|at) проявляется начальный литерал th, что позволяет задействовать ряд других оптимизаций.
  • Привязка к началу текста/логической строки. Эта разновидность оптимизации понимает, что регулярные выражения, начинающиеся с ^, могут совпасть только от начала строки, поэтому их не следует применять с других позиций.
  • Привязка к концу текста/логической строки. Эта разновидность оптимизации основана на том, что совпадения некоторых регулярных выражений, завершающихся метасимволом $ или другими якорями конца строки, должны отделяться от конца строки определенным количеством байтов. Например, для выражения regex(es)?$ совпадение должно начинаться не более чем за восемь символов от конца строки, поэтому механизм может сразу перейти к этой позиции. При большой длине целевого текста это существенно сокращает количество начальных позиций поиска. Восемь, а не семь, потому что во многих диалектах $ может совпадать перед завершающим символом новой строки.
  • Исключение по первому символу/классу/подстроке. Данный вид оптимизации руководствуется информацией (любое совпадение должно начинаться с конкретного символа или подстроки), на основании которой производится быстрая проверка и применение регулярного выражения только с соответствующих позиций строки. Например, выражение this|that|other может совпадать только в позициях, начинающихся с ; механизм проверяет все символы строки и применяет выражение только с соответствующих позиций, что может привести к огромной экономии времени. Чем длиннее проверяемая строка, тем меньше вероятность ложной идентификации начальных позиций.
  • Используйте несохраняющие круглые скобки. Если вы не используете текст, совпадающий с подвыражениями в круглых скобках, используйте несохраняющие скобки (?:…). Помимо прямого выигрыша из-за отсутствия затрат на сохранение появляется побочная экономия – состояния, используемые при возврате, становятся менее сложными и поэтому быстрее восстанавливаются.

Логические Операторы

Java Regex API поддерживает набор логических операторов, которые можно использовать для объединения нескольких подшаблонов в одном регулярном выражении, а именно оператор and и оператор or.

String text = "Cindarella and Sleeping Beauty sat in a tree";

Pattern pattern = Pattern.compile(".*");
Matcher matcher = pattern.matcher(text);

System.out.println("matcher.matches() = " + matcher.matches());

Поскольку в регулярном выражении между этими подшаблонами нет символов, между ними неявно существует оператор and. Это означает, что целевая строка должна соответствовать всем 3 подшаблонам в данном порядке, чтобы соответствовать регулярному выражению в целом. Как видно из строки, выражение соответствует строке. Строка должна начинаться с заглавной или строчной буквы C, за которой следует заглавная или строчная буква I, а затем ноль или более символов. Строка соответствует этим критериям.

String text = "Cindarella and Sleeping Beauty sat in a tree";

Pattern pattern = Pattern.compile(".*Ariel.*|.*Sleeping Beauty.*");
Matcher matcher = pattern.matcher(text);

System.out.println("matcher.matches() = " + matcher.matches());

Как вы можете видеть, шаблон будет соответствовать либо подчиненному шаблону Ariel, либо подчиненному шаблону Sleeping Beauty где-то в целевой строке. Поскольку целевая строка содержит текст «Sleeping Beauty», выражение соответствует целевой строке.

Inline Modifiers

(?s)(?m)

Modifier Legend Example Sample Match
(?i)

(except JavaScript)

(?i)Monday monDAY
(?s) (except JS and Ruby). The dot (.) matches new line characters (\r\n). Also known as «single-line mode» because the dot treats the entire input as a single line (?s)From A.*to Z From Ato Z
(?m)

(except Ruby and JS) ^ and $ match at the beginning and end of every line

(?m)1\r\n^2$\r\n^3$ 123
(?m) : the same as (?s) in other engines, i.e. DOTALL mode, i.e. dot matches line breaks (?m)From A.*to Z From Ato Z
(?x)

(except JavaScript). Also known as comment mode or whitespace mode

(?x) # this is a# commentabc # write on multiple# linesd # spaces must be# in brackets abc d
(?n) Turns all (parentheses) into non-capture groups. To capture, use .
(?d) The dot and the ^ and $ anchors are only affected by \n
(?^) Unsets ismnx modifiers

Параметры регулярных выраженийRegular Expression Options

Можно определить параметры, управляющие интерпретацией шаблона регулярного выражения обработчиком регулярных выражений.You can specify options that control how the regular expression engine interprets a regular expression pattern. Многие из этих параметров можно указать в шаблоне регулярного выражения либо в виде одной или нескольких констант RegexOptions.Many of these options can be specified either inline (in the regular expression pattern) or as one or more RegexOptions constants. Этот краткий справочник перечисляет только встраиваемые параметры.This quick reference lists only inline options. Дополнительные сведения о встроенных параметрах и параметрах RegexOptions см. в статье Параметры регулярных выражений.For more information about inline and RegexOptions options, see the article Regular Expression Options.

Встроенный параметр можно задать двумя способами:You can specify an inline option in two ways:

  • С помощью прочих конструкций , где минус (-) перед параметром или набором параметров отключает эти параметры.By using the miscellaneous construct , where a minus sign (-) before an option or set of options turns those options off. Например, включает сопоставление без учета регистра (), отключает многострочный режим () и отключает захват неименованных групп ().For example, turns case-insensitive matching () on, turns multiline mode () off, and turns unnamed group captures () off. Параметр применяется к шаблону регулярного выражения от точки, в которой определен параметр, и действует либо до конца шаблона, либо до точки, в которой другая конструкция отменяет параметр.The option applies to the regular expression pattern from the point at which the option is defined, and is effective either to the end of the pattern or to the point where another construct reverses the option.
  • С помощью конструкции группированиячасть выражения, которая определяет параметры для только для указанной группы.By using the grouping constructsubexpression, which defines options for the specified group only.

Механизм регулярных выражений .NET поддерживает следующие встроенные параметры:The .NET regular expression engine supports the following inline options:

ПараметрOption ОписаниеDescription ШаблонPattern Число соответствийMatches
Использовать соответствие без учета регистра.Use case-insensitive matching. , в , in
Использовать многострочный режим.Use multiline mode. и соответствуют началу и концу строки (line), а не началу и концу строки (string). and match the beginning and end of a line, instead of the beginning and end of a string. Пример см. в подразделе «Многострочный режим» раздела Параметры регулярных выражений.For an example, see the «Multiline Mode» section in Regular Expression Options.
Не захватывать неименованные группы.Do not capture unnamed groups. Пример см. в подразделе «Только явные захваты» раздела Параметры регулярных выражений.For an example, see the «Explicit Captures Only» section in Regular Expression Options.
Использовать однострочный режим.Use single-line mode. Пример см. в подразделе «Однострочный режим» раздела Параметры регулярных выражений.For an example, see the «Single-line Mode» section in Regular Expression Options.
Игнорировать знаки пробела в шаблоне регулярного выражения, не преобразованные в escape-последовательность.Ignore unescaped white space in the regular expression pattern. , в , in

Строковые методы, поиск и замена

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

Все методы, кроме replace, можно вызывать как с объектами типа regexp в аргументах, так и со строками, которые автоматом преобразуются в объекты RegExp.

Так что вызовы эквивалентны:

var i = str.search(/\s/)
var i = str.search("\\s")

При использовании кавычек нужно дублировать \ и нет возможности указать флаги. Если регулярное выражение уже задано строкой, то бывает удобна и полная форма

var regText = "\\s"
var i = str.search(new RegExp(regText, "g"))

Возвращает индекс регулярного выражения в строке, или -1.

Если Вы хотите знать, подходит ли строка под регулярное выражение, используйте метод (аналогично RegExp-методы ). Чтобы получить больше информации, используйте более медленный метод (аналогичный методу ).

Этот пример выводит сообщение, в зависимости от того, подходит ли строка под регулярное выражение.

function testinput(re, str){
   if (str.search(re) != -1)
      midstring = " contains ";
   else
      midstring = " does not contain ";
   document.write (str + midstring + re.source);
}

Если в regexp нет флага , то возвращает тот же результат, что .

Если в regexp есть флаг , то возвращает массив со всеми совпадениями.

Чтобы просто узнать, подходит ли строка под регулярное выражение , используйте .

Если Вы хотите получить первый результат — попробуйте r.

В следующем примере используется, чтобы найти «Chapter», за которой следует 1 или более цифр, а затем цифры, разделенные точкой. В регулярном выражении есть флаг , так что регистр будет игнорироваться.

str = "For more information, see Chapter 3.4.5.1";
re = /chapter (\d+(\.\d)*)/i;
found = str.match(re);
alert(found);

Скрипт выдаст массив из совпадений:

  • Chapter 3.4.5.1 — полностью совпавшая строка
  • 3.4.5.1 — первая скобка
  • .1 — внутренняя скобка

Следующий пример демонстрирует использование флагов глобального и регистронезависимого поиска с . Будут найдены все буквы от А до Е и от а до е, каждая — в отдельном элементе массива.

var str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
var regexp = //gi;
var matches = str.match(regexp);
document.write(matches);

// matches = 

Метод replace может заменять вхождения регулярного выражения не только на строку, но и на результат выполнения функции. Его полный синтаксис — такой:

var newString = str.replace(regexp/substr, newSubStr/function)
Объект RegExp. Его вхождения будут заменены на значение, которое вернет параметр номер 2
Строка, которая будет заменена на .
Строка, которая заменяет подстроку из аргумента номер 1.
Функция, которая может быть вызвана для генерации новой подстроки (чтобы подставить ее вместо подстроки, полученной из аргумента 1).

Метод не меняет строку, на которой вызван, а просто возвращает новую, измененную строку.

Чтобы осуществить глобальную замену, включите в регулярное выражение флаг .

Если первый аргумент — строка, то она не преобразуется в регулярное выражение, так что, например,

var ab = "a b".replace("\\s","..") // = "a b"

Вызов replace оставил строку без изменения, т.к искал не регулярное выражение , а строку «\s».

В строке замены могут быть такие спецсимволы:

Pattern Inserts
Вставляет «$».
Вставляет найденную подстроку.
Вставляет часть строки, которая предшествует найденному вхождению.
Вставляет часть строки, которая идет после найденного вхождения.
or Где или — десятичные цифры, вставляет подстроку вхождения, запомненную -й вложенной скобкой, если первый аргумент — объект RegExp.

Если Вы указываете вторым параметром функцию, то она выполняется при каждом совпадении.

В функции можно динамически генерировать и возвращать строку подстановки.

Первый параметр функции — найденная подстрока. Если первым аргументом является объект , то следующие параметров содержат совпадения из вложенных скобок. Последние два параметра — позиция в строке, на которой произошло совпадение и сама строка.

Например, следующий вызов возвратит XXzzzz — XX , zzzz.

function replacer(str, p1, p2, offset, s)
{
return str + " - " + p1 + " , " + p2;
}
var newString = "XXzzzz".replace(/(X*)(z*)/, replacer)

Как видите, тут две скобки в регулярном выражении, и потому в функции два параметра , .
Если бы были три скобки, то в функцию пришлось бы добавить параметр .

Следующая функция заменяет слова типа на :

function styleHyphenFormat(propertyName)
{
  function upperToHyphenLower(match)
  {
    return '-' + match.toLowerCase();
  }
  return propertyName.replace(//, upperToHyphenLower);
}

Special characters

Escapes also allow you to specify individual characters that are otherwise hard to type. You can specify individual unicode characters in five ways, either as a variable number of hex digits (four is most common), or by name:

  • : 2 hex digits.

  • : 1-6 hex digits.

  • : 4 hex digits.

  • : 8 hex digits.

  • , e.g.  matches the basic smiling emoji.

Similarly, you can specify many common control characters:

  • : bell.

  • : match a control-X character.

  • : escape ().

  • : form feed ().

  • : line feed ().

  • : carriage return ().

  • : horizontal tabulation ().

  • match an octal character. ‘ooo’ is from one to three octal digits, from 000 to 0377. The leading zero is required.

Строковые методы, поиск и замена

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

Все методы, кроме replace, можно вызывать как с объектами типа regexp в аргументах, так и со строками, которые автоматом преобразуются в объекты RegExp.

Так что вызовы эквивалентны:

var i = str.search(/\s/)
var i = str.search("\\s")

При использовании кавычек нужно дублировать \ и нет возможности указать флаги. Если регулярное выражение уже задано строкой, то бывает удобна и полная форма

var regText = "\\s"
var i = str.search(new RegExp(regText, "g"))

Возвращает индекс регулярного выражения в строке, или -1.

Если Вы хотите знать, подходит ли строка под регулярное выражение, используйте метод (аналогично RegExp-методы ). Чтобы получить больше информации, используйте более медленный метод (аналогичный методу ).

Этот пример выводит сообщение, в зависимости от того, подходит ли строка под регулярное выражение.

function testinput(re, str){
   if (str.search(re) != -1)
      midstring = " contains ";
   else
      midstring = " does not contain ";
   document.write (str + midstring + re.source);
}

Если в regexp нет флага , то возвращает тот же результат, что .

Если в regexp есть флаг , то возвращает массив со всеми совпадениями.

Чтобы просто узнать, подходит ли строка под регулярное выражение , используйте .

Если Вы хотите получить первый результат — попробуйте r.

В следующем примере используется, чтобы найти «Chapter», за которой следует 1 или более цифр, а затем цифры, разделенные точкой. В регулярном выражении есть флаг , так что регистр будет игнорироваться.

str = "For more information, see Chapter 3.4.5.1";
re = /chapter (\d+(\.\d)*)/i;
found = str.match(re);
alert(found);

Скрипт выдаст массив из совпадений:

  • Chapter 3.4.5.1 — полностью совпавшая строка
  • 3.4.5.1 — первая скобка
  • .1 — внутренняя скобка

Следующий пример демонстрирует использование флагов глобального и регистронезависимого поиска с . Будут найдены все буквы от А до Е и от а до е, каждая — в отдельном элементе массива.

var str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
var regexp = //gi;
var matches = str.match(regexp);
document.write(matches);

// matches = 

Метод replace может заменять вхождения регулярного выражения не только на строку, но и на результат выполнения функции. Его полный синтаксис — такой:

var newString = str.replace(regexp/substr, newSubStr/function)
Объект RegExp. Его вхождения будут заменены на значение, которое вернет параметр номер 2
Строка, которая будет заменена на .
Строка, которая заменяет подстроку из аргумента номер 1.
Функция, которая может быть вызвана для генерации новой подстроки (чтобы подставить ее вместо подстроки, полученной из аргумента 1).

Метод не меняет строку, на которой вызван, а просто возвращает новую, измененную строку.

Чтобы осуществить глобальную замену, включите в регулярное выражение флаг .

Если первый аргумент — строка, то она не преобразуется в регулярное выражение, так что, например,

var ab = "a b".replace("\\s","..") // = "a b"

Вызов replace оставил строку без изменения, т.к искал не регулярное выражение , а строку «\s».

В строке замены могут быть такие спецсимволы:

Pattern Inserts
Вставляет «$».
Вставляет найденную подстроку.
Вставляет часть строки, которая предшествует найденному вхождению.
Вставляет часть строки, которая идет после найденного вхождения.
or Где или — десятичные цифры, вставляет подстроку вхождения, запомненную -й вложенной скобкой, если первый аргумент — объект RegExp.

Если Вы указываете вторым параметром функцию, то она выполняется при каждом совпадении.

В функции можно динамически генерировать и возвращать строку подстановки.

Первый параметр функции — найденная подстрока. Если первым аргументом является объект , то следующие параметров содержат совпадения из вложенных скобок. Последние два параметра — позиция в строке, на которой произошло совпадение и сама строка.

Например, следующий вызов возвратит XXzzzz — XX , zzzz.

function replacer(str, p1, p2, offset, s)
{
return str + " - " + p1 + " , " + p2;
}
var newString = "XXzzzz".replace(/(X*)(z*)/, replacer)

Как видите, тут две скобки в регулярном выражении, и потому в функции два параметра , .
Если бы были три скобки, то в функцию пришлось бы добавить параметр .

Следующая функция заменяет слова типа на :

function styleHyphenFormat(propertyName)
{
  function upperToHyphenLower(match)
  {
    return '-' + match.toLowerCase();
  }
  return propertyName.replace(//, upperToHyphenLower);
}

Replacing Regex Matches in String Vectors

The sub function has three required parameters: a string with the regular expression, a string with the replacement text, and the input vector. sub returns a new vector with the same length as the input vector. If a regex match could be found in a string element, it is replaced with the replacement text. Only the first match in each string element is replaced. If no matches could be found in some strings, those are copied into the result vector unchanged.

Use gsub instead of sub to replace all regex matches in all the string elements in your vector. Other than replacing all matches, gsub works in exactly the same way, and takes exactly the same arguments.

R uses its own replacement string syntax. Even though R 4.0.0 uses the PCRE2 regex flavor when you pass perl=TRUE, it still uses the R replacement string syntax. There is no option to use the PCRE2 replacement string syntax.

You can use the backreferences \1 through \9 in the replacement text to reinsert text matched by a capturing group. You cannot use backreferences to groups 10 and beyond. If your regex has named groups, you can use numbered backreferences to the first 9 groups. There is no replacement text token for the overall match. Place the entire regex in a capturing group and then use \1 to insert the whole regex match.

> sub("(a+)", "z\\1z", c("abc", "def", "cba a", "aa"), perl=TRUE)
 "zazbc"  "def"  "cbzaz a"   "zaaz"
> gsub("(a+)", "z\\1z", c("abc", "def", "cba a", "aa"), perl=TRUE)
 "zazbc"  "def"  "cbzaz zaz" "zaaz"

You can use \U and \L to change the text inserted by all following backreferences to uppercase or lowercase. You can use \E to insert the following backreferences without any change of case. These escapes do not affect literal text.

> sub("(a+)", "z\\U\\1z", c("abc", "def", "cba a", "aa"), perl=TRUE)
 "zAzbc"  "def"  "cbzAz a"   "zAAz"
> gsub("(a+)", "z\\U\\1z", c("abc", "def", "cba a", "aa"), perl=TRUE)
 "zAzbc"  "def"  "cbzAz zAz" "zAAz"

A very powerful way of making replacements is to assign a new vector to the regmatches function when you call it on the result of gregexpr. The vector you assign should have as many elements as the original input vector. Each element should be a character vector with as many strings as there are matches in that element. The original input vector is then modified to have all the regex matches replaced with the text from the new vector.

> x <- c("abc", "def", "cba a", "aa")
> m <- gregexpr("a+", x, perl=TRUE)
> regmatches(x, m) <- list(c("one"), character(0), c("two", "three"), c("four"))
> x
  "onebc"       "def"         "cbtwo three" "four"

Завершители строк Unicode

В Unicode определяется несколько символов (а также одна последовательность из двух символов), которые считаются завершителями строк (line terminators).

Завершители строк в Юникоде
Символ Описание
LF U+000A Перевод строки (ASCII)
VT U+000B Вертикальная табуляция (ASCII)
FF U+000C Перевод формата (ASCII)
CR U+000D Возврат каретки (ASCII)
CR/LF U+000D U+000A Возврат каретки/перевод строки (ASCII последовательность)
NEL Следующая строка (Юникод)
LS U+2028 Разделитель строк (Юникод)
PS U+2029 Разделитель абзацев (Юникод)

При наличии полноценной поддержки со стороны программы завершители строк влияют на результаты чтения строк из файла (в сценарных языках – включая файл, из которого читается программа). В регулярных выражениях они могут влиять как на то, какие символы совпадают с ., так и на возможность совпадения метасимволов ^, $ и \Z

Статичные регэкспы

В некоторых реализациях javascript регэкспы, заданные коротким синтаксисом /…/ — статичны. То есть, такой объект создается один раз в некоторых реализациях JS, например в Firefox. В Chrome все ок.

function f() {
  // при многократных заходах в функцию объект один и тот же
  var re = /lalala/     
}

По стандарту эта возможность разрешена ES3, но запрещена ES5.

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

При поиске всех совпадений в цикле проблем не возникает, т.к. последняя итерация (неудачная) обнуляет .

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector