regex — вопросы с ответами

Основы

Regex (регулярные выражения) – это специально закодированные текстовые строки, используемые в качестве шаблонов для сопоставления наборов строк. Они начали появляться в 1940-х годах как способ описания обычных языков, но по-настоящему начали использоваться в программировании в 1970-х годах.

Позднее регулярные выражения стали важной частью набора инструментов, появившихся в операционной системе Unix – редакторы ed, sed и vi (vim), grep, AWK и другие. Но способы реализации регулярных выражений не всегда были такими регулярными.

Регулярные выражения имеют репутацию прямолинейных элементов, но все зависит от того, как вы к ним подходите. Существует естественная прогрессия от чего-то простого:

d

Сокращение символа, которое соответствует любой цифре от 0 до 9, чему-то более сложному, например:

^((d{3})|^d{3}[.-]?)?d{3}[.-]?d{4}$

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

Простое сопоставление с образцом

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

  • Строковые литералы;
  • Однозначные числа;
  • Буквы;
  • Символы любого рода.

Одна из наиболее интересных особенностей заключается в том, что, изучив синтаксис, вы сможете использовать этот инструмент практически во всех языках программирования (JavaScript, Java, VB, C#, C/C++, Python, Perl, Ruby. Delphi, R, Tcl и многие другие) с малейшими отличиями в отношении поддержки наиболее продвинутых функций и версий синтаксиса, поддерживаемых механизмами).

Синтаксис и команды

Выражения состоят из одной или нескольких ветвей, отделенных друг от друга символом '|'. Регулярное выражение соответствует любой строке, которая соответствует любой из его ветвей.

Например, регулярное выражение

a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z

соответствует любому (одному) строчному символу английского алфавита.

Каждая ветвь в Regex состоит из частей, которые составлены путем сопоставления. Строка соответствует регулярному выражению, если оно содержит совпадение для первого фрагмента, за которым (сразу) следует совпадение для второго фрагмента, затем (немедленно) – совпадение для третьего фрагмента и т. д.

Например, каждая литеральная строка, которая не содержит специальных символов, таких как «Maple», может пониматься как объединение частей M, a, p, l и e. Строка

The fastest computer algebra system is Maple, of course!

соответствует регулярному выражению Maple, поскольку оно содержит совпадение (M) для первого фрагмента, за которым сразу же следует совпадение для второго фрагмента (a) и т. д.

Хотя простые выражения в Regex, такие как Maple, подвергаются дальнейшему разложению, на практике их обычно считают «морально атомарными», потому что они всегда совпадают таким простым и понятным способом. (Их разложение на отдельные символы – просто техническое удобство.)

Часть состоит из атома, за которым может следовать один из символов '*', '+' или '?'. Назначение этих символов следующее:

  • Строка соответствует фрагменту формы a*, где a представляет собой атом, если он соответствует нулю или более последовательных вхождений a;
  • Строка соответствует фрагменту формы a+, где a представляет собой атом, если он соответствует одному или нескольким последовательным вхождениям a;
  • Строка соответствует фрагменту формы a?, где a – атом, если он соответствует нулю или одному вхождению a.

Поскольку все буквы алфавита представляют собой атомы, каждый из u, u+, u* и u? являются примерами кусочков, основанных на атомарном регулярном выражении u, состоящем из одного символа 'u'. Первый из них, u, соответствует единственному вхождению буквы «u». Регулярное выражение u+ соответствует любой последовательности из одного или нескольких u. Например, все u, uu и uuuuuuu совпадают, но uuv не совпадает.

Пока предположим, что строка (Fred), то есть фрагмент Fred, заключенный в скобки, является атомом и соответствует тем же строкам, что и регулярное выражение Fred. Тогда каждый из (Fred), (Fred)?, (Fred)+ и (Fred)*, являются частями. Первый из них (Fred) соответствует любой строке, содержащей подстроку «Fred». Второй пример (Fred)?, соответствует нулю или одному вхождению строки «Fred» (таким образом, сам по себе он соответствует каждой строке. Как правило, это будет использоваться как часть большего регулярного выражения). Регулярное выражение (Fred)+ соответствует любой строке, содержащей одно или несколько смежных вхождений строки «Fred» : "aFredz", "aFredFredz", "aFredFredFredz" и так далее. Регулярное выражение (Fred)* похоже, соответствует всему, что соответствует (Fred)+, но также соответствует нулевому вхождению строки «Fred»: и "az", и "aFredz" (опять же, само по себе это регулярное выражение соответствует любой строке).

Специальные символы

Как упоминалось ранее, одиночные буквенно-цифровые символы являются примерами атомов Regex. Фактически, любой нестандартный символ – это атом, то есть любой символ, кроме одного из следующих специальных символов:

^ . $ [ ] ( ) | * + ?

Каждый из этих специальных символов подлежит специальной интерпретации в структуре регулярного выражения (некоторые из которых уже встречались). Любой из этих символов может быть включен буквально в регулярное выражение, экранируя его символом (обратный слеш). Например, a+ b соответствует строке "a+b", но не строке "aaaab", которой соответствует регулярное выражение a+b. Когда символ предшествует не спецсимволу, он такой же, как если бы вообще не появлялся. Например, регулярные выражения ab и ab эквивалентны. Символ обратной косой черты не может быть последним символом в регулярном выражении.

Регулярное выражение () и привязанные регулярные выражения

В дополнение к неспецифическим символам атом может быть регулярным выражением (), которое соответствует пустой строке, или любым регулярным выражением re, заключенным в скобки: (re). Это соответствует любому совпадению для содержащегося регулярного выражения re и используется в качестве устройства группировки (например, в приведенных выше примерах (Fred)+).

В качестве примера использования скобок рассмотрим разницу между двумя регулярными выражениями (Fred)+ и Fred+. Первый соответствует повторяющимся вхождениям строки «Fred», а второй соответствует таким строкам, как «Fred», «Fredd», «Freddd», «Fredddd» и т. д.

Односимвольное регулярное выражение '.' (одна точка) – это атом. Оно соответствует любому символу. Например, регулярное выражение ... соответствует любой строке длины три.

Специальные символы '^'и '$' также являются атомарными регулярными выражениями. Регулярное выражение ^ соответствует пустой строке в начале любой строки, в то время как $ соответствует пустой строке в конце строки. Так, например, регулярное выражение ^Fred$ соответствует точной строке «Fred», но не «aFredz» (что соответствует Fred). Регулярные выражения, использующие ^ или $, иногда называют привязанными регулярными выражениями.

Выражение в скобках

Атомы также включают выражения в скобках. Выражение в скобках – это последовательность символов, заключенная в квадратные скобки [ и ]. В простейшем случае выражение в скобках соответствует любому из символов в скобках. По этой причине их иногда также называют классами символов. Например, регулярное выражение [aeiouAEIOU] соответствует любой гласной в Regex, а [aeiouAEIOU]+ соответствует любой последовательности из одной или нескольких гласных в любом порядке. Однако в скобочных выражениях допускается несколько специальных конструкций и сокращений.

Если первым символом после открывающей скобки выражения является символ ^, то значение выражения в скобках меняется на противоположное, то есть оно соответствует любому символу, не входящему в набор символов, описанных (остальной частью) выражением в скобках. Например, регулярное выражение [^aeiouAEIOU] соответствует согласным и любому регистру буквы 'y'.

Диапазон символов может быть включен в выражение в скобках. Диапазоны указываются путем разделения двух символов на символ '-'. Таким образом, строчные буквы алфавита могут быть сокращены как регулярное выражение [a-z].

Диапазоны могут быть встроены в любое место в выражении в скобках, и в одном выражении в скобках может быть несколько диапазонов. Каждый из [a-zA-Z], [0-35-7A-G], [^a-z0-9] и [a-ab-bc-cd-de-e] являются допустимыми выражениями в скобках. Первый соответствует любому символу алфавита в верхнем или нижнем регистре, второй эквивалентен [0123567ABCDEFG], третий соответствует любому символу, кроме десятичного знака или символа алфавита в нижнем регистре, а последний пример – просто еще один способ сказать [a-e]. Недопустимо, чтобы два диапазона символов разделяли конечную точку. Например, [a-c-e] будет синтаксически неверным выражением в Regex.

Примечание: диапазоны символов сильно зависят от упорядоченных последовательностей и, следовательно, определяются параметрами языка. Как таковые, они не являются портативными. Реализация Maple устраняет этот недостаток переносимости за счет параметров, указывая, что POSIX должна использоваться для всех вычислений, включающих регулярные выражения.

Правый символ скобки ']' можно включить в выражение в скобках буквально, сделав его первым символом (за исключением ^, если он присутствует). Например, []] соответствует строке "]".

Дефис '-' 'может быть включен в выражение в скобках, сделав его первым или последним символом или сделав его конечной точкой диапазона символов. Любой из [-], [---] и [--a] будет соответствовать дефису (но не взаимно эквивалентны). Обратите внимание, что [a--] является синтаксической ошибкой, потому что символ 'a' следует за символом '-' в последовательности сортировки языкового стандарта POSIX.

9 ответов
Я хочу извлечь подстроки из строки, соответствующей шаблону регулярного выражения. Итак, я ищу что-то вроде этого: func matchesForRegexInText(regex: String!, text: String!) -> [String] { ??? } Итак, это то, что у меня есть: func matchesForRegexInText(regex: String!, text: String!) -> [Stri...
string
10 янв. 2015, в 18:09
6 ответов
Вчера я сделал комментарий, где кто-то использовал [0123456789] в регулярном выражении, а не [0-9] или \d. Я сказал, что, вероятно, более эффективно использовать спецификатор диапазона или цифры, чем набор символов. Я решил проверить это сегодня и, с удивлением обнаружил, что (по крайней мере, в дви...
performance
18 май 2013, в 08:35
12 ответов
Я хотел бы использовать регулярное выражение в sqlite, но я не знаю, как это сделать. В моей таблице есть столбец со строками: "3,12,13,14,19,28,32" Теперь, если я набираю "where x LIKE" 3 ", я также получаю строки, которые содержат значения, такие как 13 или 32, но я хотел бы получить только строки...
query-string
21 фев. 2011, в 21:24
18 ответов
$string = " put returns between paragraphs for linebreak add 2 spaces at end "; Хотите удалить все новые строки из строки. У меня есть это регулярное выражение, оно может поймать всех из них, проблема в том, что я не знаю, с какой функцией его использовать. /\r\n|\r|\n/ $string должен стать: $s...
string
21 сен. 2010, в 14:15
10 ответов
Как удалить все не буквенно-цифровые символы из строки, кроме символов пробела и пробела?
09 июль 2010, в 08:31
46 ответов
У меня есть эта строка: "Test abc test test abc test test test abc test test abc" Выполнение str = str.replace('abc', ''); похоже, удаляет только первое вхождение abc в строку выше. Как я могу заменить все его появление?
string
replace
17 июль 2009, в 17:36
84 ответа
Как сделать первую букву строки в верхнем регистре, но не изменить случай любой из других букв? Например: "this is a test" → "this is a test" "the Eiffel Tower" → "the Eiffel Tower" "/index.html" → "/index.html"
string
letter
capitalize
22 июнь 2009, в 09:23
12 ответов
Я хочу заменить пробел символом подчеркивания в строке, чтобы создать хорошие URL-адреса. Так что, например: "This should be connected" becomes "This_should_be_connected" Я использую Python с Django. Можно ли это решить с помощью регулярных выражений?...
17 июнь 2009, в 15:36
11 ответов
У меня есть таблица с ~ 500 тыс. строк; varchar (255) столбец UTF8 filename содержит имя файла; Я пытаюсь вычеркнуть различные странные символы из имени файла - подумал, что я бы использовал класс символов: [^a-zA-Z0-9()_ .\-] Теперь есть функция в MySQL, которая позволяет вам заменять регулярное в...
mysql-udf
12 июнь 2009, в 15:28
30 ответов
Как я могу написать две функции, которые берут строку и возвращаются, если она начинается с указанного символа/строки или заканчивается им? Например: $str = '|apples}'; echo startsWith($str, '|'); //Returns true echo endsWith($str, '}'); //Returns true ...
string
07 май 2009, в 12:44
8 ответов
Мне нужно удалить все символы из строки, которые не находятся в a-z A-Z 0-9, или не являются пробелами. Есть ли у кого-нибудь функция для этого?
string
18 март 2009, в 17:00
19 ответов
Я хотел бы создать метод String.replaceAll() в JavaScript, и я думаю, что использование RegEx было бы самым сложным способом сделать это. Однако я не могу понять, как передать переменную в RegEx. Я могу сделать это уже, что заменит все экземпляры "B" на "A". "ABABAB".replace(/B/g, "A"); Но я хочу с...
29 янв. 2009, в 22:33
15 ответов
Я хочу сопоставить часть строки, используя регулярное выражение, а затем получить доступ к этой подстроке в скобках: var myString = "something format_abc"; // I want "abc" var arr = /(?:^|\s)format_(.*?)(?:\s|$)/.exec(myString); console.log(arr); // Prints: [" format_abc", "abc"] .. so far so ...
11 янв. 2009, в 05:50
20 ответов
Как заменить несколько пробелов в строке только одним пробелом в С#? Пример: 1 2 3 4 5 : 1 2 3 4 5
string
15 окт. 2008, в 22:52
79 ответов
Как проверить адрес электронной почты на JavaScript?
validation
email
email-validation
05 сен. 2008, в 15:48
Наверх
Меню