Тестер и генератор регулярных выражений
Содержание:
- Запрет возврата
- Крепление стропил к мауэрлату: основные варианты, правила и схемы
- regexp.exec(str)
- Указание количества повторений символов в тексте
- Примеры preg_match PHP
- Скобки в регулярных выражениях
- Синтаксис регулярных выражений
- Строковые методы, поиск и замена
- Как они работают?¶
- Метасимволы
- Брокер — это не навсегда. Не понравится — найдете другого
- Экранирование свойств Unicode¶
- Криптоброкер KuCoin
- Как включить, настроить датчик приближения в смартфоне?
- Замена текста REGEXP_REPLACE
- Сложно, по полезно¶
- Заключение
Запрет возврата
Переписывать регулярное выражение не всегда удобно, и не всегда очевидно, как это сделать.
Альтернативный подход заключается в том, чтобы запретить возврат для квантификатора.
Движок регулярных выражений проверяет множество вариантов, которые для человека являются очевидно ошибочными.
Например, в шаблоне для человека очевидно, что в не нужно «откатывать» . От того, что вместо одного у нас будет два независимых , ничего не изменится:
Если говорить об изначальном примере , то хорошо бы исключить возврат для . То есть, для нужно искать только одно слово целиком, максимально возможной длины. Не нужно уменьшать количество повторений , пробовать разбить слово на два , и т.п.
В современных регулярных выражениях для решения этой проблемы придумали захватывающие (possessive) квантификаторы, которые такие же как жадные, но не делают возврат (то есть, по сути, они даже проще, чем жадные).
Также есть «атомарные скобочные группы» – средство, запрещающее возврат внутри скобок.
К сожалению, в JavaScript они не поддерживаются, но есть другое средство.
Мы можем исключить возврат с помощью опережающей проверки.
Шаблон, захватывающий максимальное количество повторений без возврата, выглядит так: .
Расшифруем его:
- Опережающая проверка ищет максимальное количество , доступных с текущей позиции.
- Содержимое скобок вокруг не запоминается движком, поэтому оборачиваем внутри в дополнительные скобки, чтобы движок регулярных выражений запомнил их содержимое.
- …И чтобы далее в шаблоне на него сослаться обратной ссылкой .
То есть, мы смотрим вперед – и если там есть слово , то ищем его же .
Зачем? Всё дело в том, что опережающая проверка находит слово целиком, и мы захватываем его в шаблон посредством . Поэтому мы реализовали, по сути, захватывающий квантификатор . Такой шаблон захватывает только полностью слово , не его часть.
Например, в слове он не может захватить только , и оставить для совпадения с остатком шаблона.
Вот, посмотрите, сравнение двух шаблонов:
- В первом варианте сначала забирает слово целиком, потом постепенно отступает, чтобы попробовать найти оставшуюся часть шаблона, и в конце концов находит (при этом будет соответствовать ).
- Во втором варианте осуществляет опережающую проверку и видит сразу слово , которое целиком захватывает в совпадение, так что уже нет возможности найти .
Внутрь можно вместо вставить и более сложное регулярное выражение, при поиске которого квантификатор не должен делать возврат.
Больше о связи захватывающих квантификаторов и опережающей проверки вы можете найти в статьях Regex: Emulate Atomic Grouping (and Possessive Quantifiers) with LookAhead и Mimicking Atomic Groups.
Перепишем исходный пример, используя опережающую проверку для запрета возврата:
Здесь внутри скобок стоит вместо , так как есть ещё внешние скобки. Чтобы избежать путаницы с номерами скобок, можно дать скобкам имя, например .
Проблему, которой была посвящена эта глава, называют «катастрофический возврат» (catastrophic backtracking).
Мы разобрали два способа её решения:
- Уменьшение возможных комбинаций переписыванием шаблона.
- Запрет возврата.
Крепление стропил к мауэрлату: основные варианты, правила и схемы
regexp.exec(str)
The method method returns a match for in the string . Unlike previous methods, it’s called on a regexp, not on a string.
It behaves differently depending on whether the regexp has flag .
If there’s no , then returns the first match exactly as . This behavior doesn’t bring anything new.
But if there’s flag , then:
- A call to returns the first match and saves the position immediately after it in the property .
- The next such call starts the search from position , returns the next match and saves the position after it in .
- …And so on.
- If there are no matches, returns and resets to .
So, repeated calls return all matches one after another, using property to keep track of the current search position.
In the past, before the method was added to JavaScript, calls of were used in the loop to get all matches with groups:
This works now as well, although for newer browsers is usually more convenient.
We can use to search from a given position by manually setting .
For instance:
If the regexp has flag , then the search will be performed exactly at the position , not any further.
Let’s replace flag with in the example above. There will be no matches, as there’s no word at position :
That’s convenient for situations when we need to “read” something from the string by a regexp at the exact position, not somewhere further.
Указание количества повторений символов в тексте
Все приведенные выше регулярные выражения будут совпадать только с одним символом. Чтобы указать, сколько символов должно быть тексте, чтобы произошло совпадение вы можете использовать квантификаторы.
+ – Обозначает одно или более совпадение. Например, чтобы регулярное выражение совпало с набором символов “ABD12D” нужно использовать \w+.
* – Обозначает ноль или более символов. Например, под выражение b\w* подойдут следующие сочетания символов: “b”, “bat”, “bajhdsfbfjhbe”. В данном случае мы ищем соответствие нулевому или более количеству символов в словах после буквы “b”.
{m, n} – Соответствует не менее m и не более n вхождений предыдущего символа. {m,} будет соответствовать не менее, чем m вхождений, верхнего предела в этом случае нет. {k} будет соответствовать точному количеству (k) вхождений предыдущего символа.
? – Обозначает ноль или один символ. Например, это может быть полезно при сопоставлении двух вариантов написания для одной и той же слова. Выражению будут соответствовать оба слова: “behavior” и “behaviour”.
| – Соответствует выражению до или после символа |. Например, выражению /se(a|e)/ — соответсвуют оба слова: “see” и “sea”.
Примеры preg_match PHP
1.
if (!preg_match("/^*\@*\.{2,6}$/i", $email)) exit("Неправильный адрес");
2.
// \S означает "не пробел", а + - // "любое число букв, цифр или точек". Модификатор 'i' после '/' // заставляет PHP не учитывать регистр букв при поиске совпадений. // Модификатор 's', стоящий рядом с 'i', говорит, что мы работаем // в "однострочном режиме" (см. ниже в этой главе). preg_match('/(\S+)@(+)/is', "Привет от somebody@mail.ru!", $p); // Имя хоста будет в $p, а имя ящика (до @) - в $p. echo "В тексте найдено: ящик - $p, хост - $p";
3.
if (!preg_match("|^{13,16}$|", $var)) ...
4.
if (preg_match("/(^+(*))$/" , $filename)==NULL) { echo "invalid filename"; exit; }
/\.(?:z(?:ip|{2})|r(?:ar|{2})|jar|bz2|gz|tar|rpm)$/i
/\.(?:mp3|wav|og(?:g|a)|flac|midi?|rm|aac|wma|mka|ape)$/i
/\.(?:exe|msi|dmg|bin|xpi|iso)$/i
/\.(?:jp(?:e?g|e|2)|gif|png|tiff?|bmp|ico)$/i
/\.(?:mpeg|ra?m|avi|mp(?:g|e|4)|mov|divx|asf|qt|wmv|m\dv|rv|vob|asx|ogm)$/i
5.
preg_match_all('/(8|7|\+7){0,1}{0,}({2}){0,}(({2}{0,}{2}{0,}{3})|({3}{0,}{2}{0,}{2})|({3}{0,}{1}{0,}{3})|({2}{0,}{3}{0,}{2}))/', $text, $regs );
6.
if (preg_match("/^{8,20}$/",$string)) echo "yes"; else echo "no";
7.абвгДДДеёааббаабб
if (preg_match("/(.)\\1\\1/",$string)) echo "yes"; else echo "no";
8.
preg_match("/abc/", $string); // true если найдёт в любом месте preg_match("/^abc/", $string); // true если найдёт в начале preg_match("/abc$/", $string); // true если найдёт в конце
9.
preg_match("/(ozilla.|MSIE.3)/i", $_SERVER);
Скобки в регулярных выражениях
Давай повторим, что обозначают разные виды скобок:
- Фигурные скобки задают число повторений предыдущего
символа — в этом примере выражение ищет от 1 до 5 идущих подряд
букв «a» - Квадратные скобки означают «один любой из
этих символов», в данном случае — буквы a, b, c, x, y, z или
цифра от 0 до 5. Внутри квадратных скобок не работают другие спецсимволы
вроде или — они обозначают обычный символ. Если
в квадратных скобках в начале стоит символ то смысл меняется
на противоположный: «любой один символ, кроме указанных» —
например значит «один любой символ,
кроме a, b или c». - Круглые скобки группируют символы и выражения. Например в
выражении знак «плюс» относится только
к букве c и это выражение ищет слова вроде abc, abcc, abccc. А если
поставить скобки то квантифиактор плюс относится
уже к последовательности и выражение ищет слова
abc, abcbc, abcbcbc
Примечание: в квадратных скобках можно указывать диапазоны
символов, но помни, что русская буква ё идет отдельно от
алфавита и чтобы написать «любая русская буква»,
надо писать .
Синтаксис регулярных выражений
Последнее обновление: 1.11.2015
Рассмотрим базовые моменты синтаксиса регулярных выражений.
Метасимволы
Регулярные выражения также могут использовать метасимволы — символы, которые имеют определенный смысл:
-
: соответствует любой цифре от 0 до 9
-
: соответствует любому символу, который не является цифрой
-
: соответствует любой букве, цифре или символу подчеркивания (диапазоны A–Z, a–z, 0–9)
-
: соответствует любому символу, который не является буквой, цифрой или символом подчеркивания (то есть не находится в следующих диапазонах A–Z, a–z, 0–9)
-
: соответствует пробелу
-
: соответствует любому символу, который не является пробелом
-
: соответствует любому символу
Здесь надо заметить, что метасимвол \w применяется только для букв латинского алфавита, кириллические символы для него не подходят.
Так, стандартный формат номера телефона соответствует регулярному выражению .
Например, заменим числа номера нулями:
var phoneNumber = «+1-234-567-8901»; var myExp = /\d-\d\d\d-\d\d\d-\d\d\d\d/; phoneNumber = phoneNumber.replace(myExp, «00000000000»); document.write(phoneNumber);
Модификаторы
Кроме выше рассмотренных элементов регулярных выражений есть еще одна группа комбинаций, которая указывает, как символы в строке будут повторяться. Такие комбинации еще называют модификаторами:
-
: соответствует n-ому количеству повторений предыдущего символа. Например, соответствует подстроке «hhh»
-
: соответствует n и более количеству повторений предыдущего символа. Например, соответствует подстрокам «hhh», «hhhh», «hhhhh» и т.д.
-
: соответствует от n до m повторений предыдущего символа. Например, соответствует подстрокам «hh», «hhh», «hhhh».
-
: соответствует одному вхождению предыдущего символа в подстроку или его отсутствию в подстроке. Например, соответствует подстрокам «home» и «ome».
-
: соответствует одному и более повторений предыдущего символа
-
: соответствует любому количеству повторений или отсутствию предыдущего символа
-
: соответствует началу строки.
Например, соответствует строке «home», но не «ohma», так как h должен представлять начало строки
-
: соответствует концу строки. Например, соответствует строке «дом», так как строка должна оканчиваться на букву м
Например, возьмем номер тот же телефона. Ему соответствует регулярное выражение . Однако с помощью выше рассмотренных комбинаций мы его можем упростить:
Также надо отметить, что так как символы ?, +, * имеют особый смысл в регулярных выражениях, то чтобы их использовать в обычным для них значении (например, нам надо заменить знак плюс в строке на минус), то данные символы надо экранировать с помощью слеша:
var phoneNumber = «+1-234-567-8901»; var myExp = /\+\d-\d{3}-\d{3}-\d{4}/; phoneNumber = phoneNumber.replace(myExp, «80000000000»); document.write(phoneNumber);
Отдельно рассмотрим применение комбинации ‘\b’, которая указывает на соответствие в пределах слова. Например, у нас есть следующая строка: «Языки обучения: Java, JavaScript, C++». Со временем мы решили, что Java надо заменить на C#. Но простая замена приведет также к замене строки «JavaScript» на «C#Script», что недопустимо. И в этом случае мы можем проводить замену, если регуляное выражение соответствует всему слову:
var initialText = «Языки обучения: Java, JavaScript, C++»; var exp = /Java\b/g; var result = initialText.replace(exp, «C#»); document.write(result); // Языки обучения: C#, JavaScript, C++
Но при использовании ‘\b’ надо учитывать, что в JavaScript отсутствует полноценная поддержка юникода, поэтому применять ‘\b’ мы сможем только к англоязычным словам.
Использование групп в регулярных выражениях
Для поиска в строке более сложных соответствий применяются группы. В регулярных выражениях группы заключаются в скобки. Например, у нас есть следующий код html, который содержит тег изображения: ‘<img src=»https://steptosleep.ru/wp-content/uploads/2018/06/47616.png» />’. И допустим, нам надо вычленить из этого кода пути к изображениям:
var initialText = ‘<img src= «picture.png» />’; var exp = /+\.(png|jpg)/i; var result = initialText.match(exp); result.forEach(function(value, index, array){ document.write(value + «<br/>»); })
Вывод браузера:
picture.png png
Первая часть до скобок (+\.) указывает на наличие в строке от 1 и более символов из диапазона a-z, после которых идет точка. Так как точка является специальным символом в регулярных выражениях, то она экранируется слешем. А дальше идет группа: . Эта группа указывает, что после точки может использоваться как «png», так и «jpg».
Строковые методы, поиск и замена
Следующие методы работают с регулярными выражениями из строк.
Все методы, кроме 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); }
Как они работают?¶
Регулярное выражение, которое мы определили выше как , очень простое. Оно ищет строку без каки-либо ограничений: строка может содержать много текста, а слово находиться где-то в середине и регулярное выражение сработает. Строка может содержать только слово и регулярка опять сработает.
Это довольно просто.
Вы можете попробовать протестировать регулярное выражение с помощью метода , который возвращает логическое () значение:
В примере выше мы просто проверили удовлетворяет ли шаблону регулярного выражения, который храниться в .
Это проще простого, но вы уже знаете много о регулярных выражениях.
Метасимволы
Символ | Описание |
---|---|
. | Позволяет найти один символ, кроме символа новой строки, или символа конца строки (\n, \r, \u2028 или \u2029). |
\d | Позволяет найти символ цифры в базовом латинском алфавите. Эквивалентин использованию набору символов . |
\D | Позволяет найти любой символ, который не является цифрой в базовом латинском алфавите. Эквивалентен набору символов . |
\s | Позволяет найти одиночный пробельный символ. Под пробельным символом понимается пробел, табуляция, перевод страницы, перевод строки и другие пробельные символы Юникода. Эквивалентен набору символов . |
\S | Позволяет найти одиночный символ, который не является пробельным. Под пробельным символом понимается пробел, табуляция, перевод страницы, перевод строки и другие пробельные символы Юникода. Эквивалентен набору символов . |
Позволяет найти символ backspace (специальный символ \b, U+0008). | |
\0 | Позволяет найти символ 0 (ноль). |
\n | Позволяет найти символ новой строки. |
\f | Позволяет найти символ перевода страницы. |
\r | Позволяет найти символ возврата каретки. |
\t | Позволяет найти символ горизонтальной табуляции. |
\v | Позволяет найти символ вертикальной табуляции. |
\w | Позволяет найти любой буквенно-цифровой символ базового латинского алфавита, включая подчеркивание. Эквивалентен набору символов . |
\W | Позволяет найти любой символ, который не является символом из базового латинского алфавита. Эквивалентен набору символов . |
\cX | Позволяет найти контрольный символ в строке. Где X — буква от A до Z. Например, /\cM/ обозначает символ Ctrl-M. |
\xhh | Позволяет найти символ, используя шестнадцатеричное значение (hh — двухзначное шестнадцатеричное значение). |
\uhhhh | Позволяет найти символ, используя кодировку UTF-16 (hhhh — четырехзначное шестнадцатеричное значение). |
\u{hhhh} или \u{hhhhh} | Позволяет найти символ со значением Юникода U+hhhh или U+hhhhh (шестнадцатеричное значение). Только когда задан флаг u. |
\ | Указывает, что следующий символ является специальным и не должен интерпретироваться буквально. Для символов, которые обычно трактуются специальным образом, указывает, что следующий символ не является специальным и должен интерпретироваться буквально. |
Брокер — это не навсегда. Не понравится — найдете другого
Экранирование свойств Unicode¶
Как мы говорили выше, в шаблоне регулярного выражения вы можете использовать чтобы найти совпадение на любую цифру, чтобы найти совпадение на любой символ кроме пробела, чтобы найти совпадение на любой буквенно-числовой символ и т. д.
Экранирование свойств Unicode — это возможность ES2018, которая добавляет очень крутую функцию, расширяя эту концепцию на всех Unicode символы и добавляя и .
У любого Unicode символа есть набор свойств. Например определяет семейство языков, — это логическое значение равное для ASCII символов и т. д. Вы можете положить это свойство в фигурные скобки и регулярное выражение будет проверять чтобы его значение было истинным:
— это ещё одно логическое свойство, которое проверяет содержит ли строка тольк валидные шестнадцатеричные цифры:
Существует много других логических свойств, которые вы можете проверить просто добавив их имя в фигурные скобки, включая , , , , и другие:
В дополнении к этим бинарным свойствам, вы можете проверить любое свойство символа Unicode чтобы соответствовало конкретному значению. В примере ниже я проверяю, записана ли строка в греческом или латинском алфавите:
Прочитать больше обо всех свойствах вы можете здесь.
Криптоброкер KuCoin
Как включить, настроить датчик приближения в смартфоне?
Настроек как таковых у датчика нет, как мы разобрались выше — его основная функция — это блокировка экрана при осуществлении звонков. В разных версиях ОС Андроид и прошивок чаще всего отыскать пункт включения датчика можно в меню вызовов. Нажимаем на иконку трубки, затем на значок меню, что бы перейти к необходимым опциям.
Как найти датчик приближения
Если у вас телефон фирмы Xiaomi, модели Redmi или другой фирмы с оболочкой MIUI 10 или MIUI 9 — открываем настройки, кликаем по пункту «Телефон» (или «Настройки вызовов» для 10й версии MIUI), находим пункт «Входящие вызовы» и включаем пункт «Датчик приближения».
Включаем датчик в оболочке MIUI
Замена текста REGEXP_REPLACE
Поиск и замена — одна из лучших областей применения регулярных выражений. Текст замены может включать ссылки на части исходного выражения (называемые обратными ссылками), открывающие чрезвычайно мощные возможности при работе с текстом. Допустим, имеется список имен, разделенный запятыми, и его содержимое необходимо вывести по два имени в строке. Одно из решений заключается в том, чтобы заменить каждую вторую запятую символом новой строки. Сделать это при помощи стандартной функции нелегко, но с функцией задача решается просто. Общий синтаксис ее вызова:
REGEXP_REPLACE (исходная_строка, шаблон ]])
Здесь исходная_строка — строка, в которой выполняется поиск; шаблон — регулярное выражение, совпадение которого ищется в исходной_строке; начальная_позиция — позиция, с которой начинается поиск; модификаторы — один или несколько модификаторов, управляющих процессом поиска. Пример:
DECLARE names VARCHAR2(60) := 'Anna,Matt,Joe,Nathan,Andrew,Jeff,Aaron'; names_adjusted VARCHAR2(61); comma_delimited BOOLEAN; extracted_name VARCHAR2(60); name_counter NUMBER; BEGIN -- Искать совпадение шаблона comma_delimited := REGEXP_LIKE(names,'^(*,)+(*){1}$', 'i'); -- Продолжать, только если мы действительно -- работаем со списком, разделенным запятыми. IF comma_delimited THEN names := REGEXP_REPLACE( names, '(*),(*),', '\1,\2' || chr(10) ); END IF; DBMS_OUTPUT.PUT_LINE(names); END;
Результат выглядит так:
Anna,Matt Joe,Nathan Andrew,Jeff Aaron
При вызове функции передаются три аргумента:
- names — исходная строка;
- ‘(*),(*),’ — выражение, описывающее заменяемый текст (см. ниже);
- ‘\1,\2 ‘ || chr(10) — текст замены. \1 и \2 — обратные ссылки, заложенные в основу нашего решения. Подробные объяснения также приводятся ниже.
Выражение, описывающее искомый текст, состоит из двух подвыражений в круглых скобках и двух запятых.
- Совпадение должно начинаться с имени.
- За именем должна следовать запятая.
- Затем идет другое имя.
- И снова одна запятая.
Наша цель — заменить каждую вторую запятую символом новой строки. Вот почему выражение написано так, чтобы оно совпадало с двумя именами и двумя запятыми. Также запятые не напрасно выведены за пределы подвыражений.
Первое совпадение для нашего выражения, которое будет найдено при вызове , выглядит так:
Anna,Matt,
Два подвыражения соответствуют именам «» и «». В основе нашего решения лежит возможность ссылаться на текст, совпавший с заданным подвыражением, через обратную ссылку. Обратные ссылки и в тексте замены ссылаются на текст, совпавший с первым и вторым подвыражением. Вот что происходит:
'\1,\2' || chr(10) -- Текст замены 'Anna,\2' || chr(10) -- Подстановка текста, совпавшего -- с первым подвыражением 'Anna,Matt' || chr(10) -- Подстановка текста, совпавшего -- со вторым подвыражением
Вероятно, вы уже видите, какие мощные инструменты оказались в вашем распоряжении. Запятые из исходного текста попросту не используются. Мы берем текст, совпавший с двумя подвыражениями (имена «Anna» и «Matt»), и вставляем их в новую строку с одной запятой и одним символом новой строки.
Но и это еще не все! Текст замены легко изменить так, чтобы вместо запятой в нем использовался символ табуляции (ASCII-код 9):
names := REGEXP_REPLACE( names, '(*),(*),', '\1' || chr(9) || '\2' || chr(10) );
Теперь результаты выводятся в два аккуратных столбца:
Anna Matt Joe Nathan Andrew Jeff Aaron
Поиск и замена с использованием регулярных выражений — замечательная штука. Это мощный и элегантный механизм, с помощью которого можно сделать очень многое.
Сложно, по полезно¶
Новичкам регулярные выражения могут показаться абсолютной ерундой, а зачастую даже и профессиональным разработчикам, если не вкладывать время необходимое для их понимания.
Регулярные выражения сложно писать, сложно читать и сложно поддерживать/изменять.
Но иногда регулярные выражения это единственный разумный способ выполнить какие-то манипуляции над строками, поэтому они являются очень ценным инструментом.
Это руководство нацелено на то чтобы самым простым способом дать вам некоторое представление о регулярных выражениях в JavaScript и предоставить информацию о том как читать и создавать регулярные выражения.
Эмпирическое правило заключается в том, что простые регулярные выражения просты для чтения и записи, в то время как сложные регулярные выражения могут быстро превратиться в беспорядок, если вы не глубоко понимаете основы.
Заключение
В предыдущих статьях, были рассмотрены основы регулярных выражений, а также некоторые более сложные выражения, которые могут оказаться полезными. В следующих двух статьях объясняется, как разные символы или последовательности символов работают в регулярных выражениях.
Если после прочтения приведённых выше статей вы все еще путаетесь в регулярных выражениях, советуем вам продолжить практиковаться на примерах того, как другие люди придумывают регулярные выражения.
Оригинал статьи: https://code.tutsplus.com/tutorials/a-simple-regex-cheat-sheet—cms-31278/
Перевод: Земсков Матвей