Регулярные выражения всегда были технологией, от которой страдали многие программисты, в том числе и я. В большинстве случаев, когда мы используем некоторые регулярные выражения в процессе разработки, мы открываем Google или Baidu для прямого поиска, а затем копируем и вставляем. В следующий раз, когда вы снова столкнетесь с той же проблемой, повторится та же сцена. Поскольку это очень универсальная технология, я считаю, что стоит глубоко понять и освоить регулярные выражения. Поэтому я надеюсь, что эта статья поможет вам прояснить свое мышление, понять внутреннюю взаимосвязь между различными символами регулярных выражений и сформировать систему знаний.Когда вы столкнетесь с регулярными выражениями в следующий раз, вы сможете решить ее самостоятельно, не прибегая к помощи поиска. двигатель.
Что такое регулярные выражения
Регулярные выражения на самом деле являются инструментом.ЦельОн предназначен для сопоставления строковых шаблонов, чтобы реализовать функцию поиска и замены. Он возник в результате некоторой исследовательской работы, проведенной учеными в области математики в 1950-х годах, а затем был введен в область вычислений. Из названия мы можем понять, что этовыражения, используемые для описания правил. И его основной принцип также очень прост, то есть использование идеи конечного автомата для сопоставления с образцом. каждый может использоватьregexper.comЭтот инструмент хорошо визуализирует написанные вами регулярные выражения:
Такие как/\d\w+/
Эта регулярно сгенерированная диаграмма конечного автомата:
Для конкретной реализации алгоритма, если вам интересно, вы можете прочитать «Введение в алгоритмы».
из символов
Когда мы изучаем систематическое знание, мы должны понимать его из его основного состава. Основы регулярных выраженийсоставные элементыЕго можно разделить:персонажи и метасимволы. Символы легко понять, это основная компьютерная кодировка символов.Обычно в регулярных выражениях используются цифры и английские буквы. Метасимволы, также известные как специальные символы, представляют собой символы, используемые для представления специальной семантики. Например, ^ означает «нет», | означает «или» и так далее. С помощью этих метасимволов можно создавать мощные шаблоны выражений. Далее, давайте начнем с этих основных единиц и научимся строить регулярные выражения.
один символ
Самое простое регулярное выражение может состоять из простых цифр и букв, без особой семантики, это чисто взаимно-однозначное соответствие. Если вы хотите найти символ «а» в слове «яблоко», просто используйте/a/
Это регулярное выражение подойдет.
Но если вы хотите сопоставить специальные символы, вам нужно запросить наш первый метасимвол**\
**, это escape-символ, как следует из названия, он заставляет следующие символы терять свое первоначальное значение. Например:
я хочу соответствовать*
Этот символ, поскольку*
Сам символ является специальным символом, поэтому я использую escape-метасимволы.\
чтобы он потерял свой первоначальный смысл:
/\*/
Если символ не является специальным символом, использование escape-символа придаст ему особое значение. Нам часто нужно сопоставлять некоторые специальные символы, такие как пробелы, табуляция, возврат каретки, перевод строки и т. д., и для этого нам нужно использовать escape-символы. Чтобы облегчить запоминание, я организовал следующую таблицу и приложил метод запоминания:
Специальные символы | регулярное выражение | путь памяти |
---|---|---|
новая линия | \n | new line |
подача формы | \f | form feed |
возврат каретки | \r | return |
пробел | \s | space |
Вкладки | \t | tab |
вертикальная вкладка | \v | vertical tab |
резервный персонаж | [\b] | backspace, причина, по которой избегают использования символов [] и повторения \ b |
несколько символов
Отношение сопоставления одного символа является «один к одному», то есть регулярное выражение используется для фильтрации и сопоставления только одного символа. И этого явно недостаточно, пока вводятся интервал сбора и подстановочные знаки, может быть достигнуто соответствие «один ко многим».
В регулярных выражениях наборы определяются с помощью квадратных скобок.[
а также]
. Такие как/[123]/
Это регулярное выражение может одновременно соответствовать трем символам 1, 2 и 3. Так что, если я хочу сопоставить все числа? Запись от 0 до 9, очевидно, слишком неэффективна, поэтому метасимволы-
Может использоваться для представления интервального диапазона, используя/[0-9]/
Сможет сопоставить все номера,/[a-z]/
Он может соответствовать всем строчным буквам английского языка.
Даже с учетом способа определения наборов и диапазонов, если вы хотите одновременно сопоставить несколько символов, вам все равно придется перечислять их один за другим, что неэффективно. Таким образом, группа простых регулярных выражений для одновременного сопоставления нескольких символов является производной от регулярных выражений:
интервал соответствия | регулярное выражение | путь памяти |
---|---|---|
любой символ кроме новой строки | . | период, кроме терминаторов предложения |
одна цифра, [0-9] | \d | digit |
кроме [0-9] | \D | not digit |
один символ, включая подчеркивание, [A-Za-z0-9_] | \w | word |
символы, не являющиеся словами | \W | not word |
Совпадение с пробелами, включая пробелы, табуляции, переводы форм и новые строки. | \s | space |
соответствует непробельным символам | \S | not space |
цикл и повтор
Сопоставление символов «один к одному» и «один ко многим» закончено. Далее пришло время представить, как сопоставлять несколько символов одновременно. Чтобы сопоставить несколько символов, нам просто нужно несколько раз выполнить цикл и повторно использовать наши предыдущие обычные правила. Затем в зависимости от количества циклов мы можем разделить его на 0 раз, 1 раз, несколько раз и определенное время.
0 | 1
метасимвол?
Представляет соответствие одному символу или 0 символам. Представьте, если бы вы соответствовалиcolor
а такжеcolour
Эти два слова должны быть гарантированы одновременноu
Встречается ли этот символ или нет, можно сопоставить. Итак, ваше регулярное выражение должно выглядеть так:/colou?r/
.
>= 0
метасимвол*
Используется для обозначения совпадения 0 символов или бесконечного числа символов. Обычно используется для фильтрации некоторых необязательных строк.
>= 1
метасимвол+
Он подходит для сопоставления появления одного и того же символа 1 или более раз.
определенное количество раз
В некоторых случаях нам нужно сопоставить определенное количество повторений, метасимволов{
а также}
Используется для установки точного диапазона интервалов для повторяющихся совпадений. Если 'a' я хочу сопоставить 3 раза, то я использую/a{3}/
Этот регулярный или 'a', который я хочу сопоставить как минимум дважды, должен использовать/a{2,}/
этот регулярный.
Вот полный синтаксис:
- {x}: x次
- {min, max}: 介于min次到max次之间
- {min, }: 至少min次
- {0, max}: 至多max次
Поскольку эти метасимволы относительно абстрактны и их легко спутать, я использовал метод ассоциативной памяти для компиляции формул, чтобы их можно было вспомнить при использовании.
правила сопоставления | метасимвол | Леново путь |
---|---|---|
0 или 1 раз | ? | а такжепроситьПричинаимеютТакжебез |
0 или бесконечность | * | космический потоп,ЧенсуЛи Чжан: В начале вселенной, из ничего к существованию, и, наконец, звезды полны звезд |
1 раз или бесчисленное количество раз | + | один плюс, +1 |
определенное количество раз | {x}, {min, max} | Думайте об этом как о числовой прямой, соединяющей точку с лучом и отрезком прямой. min и max представляют левую и правую границы левого и правого интервалов соответственно. |
граница местоположения
Выше мы ввели сопоставление символов, а затем нам также потребуется сопоставление границ позиций. Во время поиска длинных текстовых строк нам часто нужно ограничить местоположение запроса. Например, я хочу найти только в начале и в конце слова.
границы слов
Слова — это основные единицы, из которых состоят предложения и статьи, и общий сценарий использования — найти определенные слова в статьях или предложениях. Такие как:
The cat scattered his food all over the room.
я хочу найтиcat
это слово, но если просто использовать/cat/
Это регулярное выражение будет соответствовать одновременноcat
а такжеscattered
эти два текста. На данный момент нам нужно использовать граничные регулярные выражения\b
, где b — первая буква границы. В обычном движке он фактически соответствует положению между символами, которые могут образовывать слова (\w), и символами, которые не могут образовывать слова (\W).
Приведенный выше пример можно переписать как/\bcat\b/
Это будет соответствоватьcat
это слово.
граница строки
После сопоставления слов давайте посмотрим, как сопоставить границы целой строки. метасимвол^
Используется для соответствия началу строки. в то время как метасимволы$
Используется для соответствия концу строки. Обратите внимание, что в длинном тексте, если мы хотим исключить интерференцию разрывов строк, нам нужно использовать многострочный режим. попытаться соответствоватьI am scq000
это предложение:
I am scq000.
I am scq000.
I am scq000.
мы можем использовать/^I am scq000\.$/m
Такое регулярное выражение, по сути, m является первой буквой нескольких строк. В дополнение к m, более часто используемыми шаблонами в обычном порядке являются i и g. Первый означает игнорировать регистр, второй означает найти все совпадающие совпадения.
Наконец, резюмируя:
границы и знаки | регулярное выражение | путь памяти |
---|---|---|
границы слов | \b | boundary |
границы без слов | \B | not boundary |
начало строки | ^ | маленькийзаостренныйтакой большой |
конец строки | $ | конецАвтор, Американский научно-фантастический фильм, Знак доллара $ |
многострочный режим | м логотип | multiple of lines |
игнорировать регистр | я отмечаю | ignore case, case-insensitive |
глобальный режим | г знак | global |
подвыражение
Сопоставление символов почти такое же, как мы представили, и более продвинутое использование должно использовать подвыражения. Регулярные выражения можно сделать более мощными, вложив рекурсию и ссылаясь на самих себя.
Эволюция регулярных выражений от простого к сложному обычно занимаетГруппировка, обратные ссылки и логическая обработкаподумал о. Используя эти три правила, можно вывести бесконечно сложные регулярные выражения.
группировка
Группировки отражены в: все с(
а также)
Регулярные выражения, содержащиеся в метасимволах, сгруппированы в группы, и каждая группа являетсяподвыражениекоторый также формирует основу для передовых регулярных выражений. Если вы просто используете простой(regex)
Синтаксис сопоставления по сути такой же, как и без группировки.Если вы хотите сыграть его мощную роль, часто необходимо комбинировать способ поиска с возвратом.
обратная ссылка
Так называемая обратная ссылка (backreference) относится к последней части ссылки шаблона на подстроку, которая была сопоставлена ранее. Вы можете думать об этом как о переменной, синтаксисе обратной ссылки, например\1
,\2
,....,в\1
представляет первое подвыражение ссылки,\2
представляет второе подвыражение ссылки и так далее. а также\0
представляет все выражение.
Предположим, теперь вы хотите сопоставить два последовательных одинаковых слова в следующем тексте, как вы это сделаете?
Hello what what is the first thing, and I am am scq000.
Используя обратные ссылки, мы можем легко написать\b(\w+)\s\1
Такая регулярность.
Обратные ссылки очень часто используются в заменяющих строках, и есть небольшие различия в синтаксисе.$1
,$2
... для ссылки на заменяемую строку. Ниже приведена демонстрация кода js:
var str = 'abc abc 123';
str.replace(/(ab)c/g,'$1g');
// 得到结果 'abg abg 123'
Если мы не хотим, чтобы подвыражение заключалось в кавычки, мы можем использоватьне захватОбычный(?:regex)
Таким образом, вы можете избежать потери памяти.
var str = 'scq000'.
str.replace(/(scq00)(?:0)/, '$1,$2')
// 返回scq00,$2
// 由于使用了非捕获正则,所以第二个引用没有值,这里直接替换为$2
Иногда нам нужно ограничить область обратных ссылок. Затем с помощью прямого поиска и обратного поиска можно достичь этой цели.
поиск вперед
Прямой поиск (lookahead) используется для ограничения суффикса. Любые(?=regex)
Включенные подвыражения используются в процессе сопоставления, чтобы ограничить сопоставление предыдущего выражения. Напримерhappy happily
За эти два слова я хочу получитьhapp
наречия в начале, то вы можете использоватьhapp(?=ily)
соответствовать. Если я хочу отфильтровать всеhapp
наречия в начале, то вы также можете использоватьнегативный взгляд впередобычныйhapp(?!ily)
, будет соответствоватьhappy
словоhapp
приставка.
обратный поиск
После введения прямого просмотра давайте представим его обратную операцию: просмотр назад. Поиск назад (lookbehind) заключается в указании части выражения, а затем, начиная с позиции, которая соответствует этому части выражения, чтобы начать поиск строки, соответствующей правилу. Возьмем простой пример:apple
а такжеpeople
оба включаютple
этот суффикс, то если я просто хочу найтиapple
изple
,Как я должен это делать? мы можем ограничитьapp
Этот префикс может быть однозначно определенple
это слово.
/(?<=app)ple/
в(?<=regex)
Синтаксис — это обратный поиск, который мы собираемся представить здесь.regex
Упомянутое подвыражение будет сопоставлено как элемент ограничения, и после того, как это подвыражение будет сопоставлено, оно продолжитназадНаходить. Другой тип ограниченного сопоставления заключается в использовании(?<!regex)
грамматика, именуемая здесьнегативный взгляд назад. В отличие от прямого поиска, указанное подвыражение не может быть сопоставлено. Итак, в приведенном выше примере, если вы хотите найтиapple
изple
также можно записать как/(?<!peo)ple
.
Следует отметить, что не каждая реализация регулярных выражений поддерживает поиск в обратном направлении. Он не поддерживается в javascript, поэтому, если поиск в обратном направлении полезен, одна из идей состоит в том, чтобы перевернуть строку, затем использовать поиск в прямом направлении, а затем перевернуть ее обратно после обработки. См. простой пример:
// 比如我想替换apple的ple为ply
var str = 'apple people';
str.split('').reverse().join('').replace(/elp(?=pa)/, 'ylp').split('').reverse().join('');
PS: Спасибо за напоминание в области комментариев, начиная с es2018, регулярные выражения в Chrome также поддерживают обратный поиск. Однако в реальных проектах нужно также обратить внимание на поддержку старых браузеров, чтобы не допустить появления багов в сети. Подробнее см. http://kangax.github.io/compat-table/es2016plus/#test-RegExp_Lookbehind_Assertions.
Наконец, просмотрите эту часть:
отступление | Обычный | путь памяти |
---|---|---|
Цитировать | \0,\1,\2 и $0, $1, $2 | побег + номер |
группа без захвата | (?:) | Выражение в кавычках (()), само по себе не используется (?), кавычка (:) |
поиск вперед | (?=) | Ссылочное подвыражение (()), не используемое само по себе (?), прямой поиск (=) |
Прямой отрицательный поиск | (?!) | Ссылочное подвыражение (()), не используемое само по себе (?), отрицательный поиск (!) |
обратный поиск | (?<=) | Ссылочное подвыражение (()), не используемое само по себе (?), назад ( |
обратный отрицательный поиск | (?<!) | Ссылочное подвыражение (()), не используемое само по себе (?), назад ( |
логическая обработка
Информатика — это наука, включающая в себя логику. Давайте вспомним три логических соотношения, используемых в языках программирования, И или НЕ.
В обычном режиме стандартными правилами по умолчанию являютсяа такжетак это здесь не обсуждается.
а такжеНетОтношение делится на два случая: один — сопоставление символов, а другой — сопоставление подвыражения. При сопоставлении символов необходимо использовать^
этот метасимвол. Здесь важно помнить:только в[
а также]
Внутреннее использование^
только выражать непричастность. Несоотношение сопоставления подвыражений будет использовать подвыражение прямого отрицательного поиска, представленное ранее.(?!regex)
или обратный отрицательный поиск подвыражений(?<!regex)
.
Или отношение, обычно используемое для классификации подвыражений. Например, если я одновременно сопоставляю a и b, я могу использовать его(a|b)
такие подвыражения.
Логика | обычные метасимволы |
---|---|
а также | без |
Нет | [^regex] и ! |
или | | |
Суммировать
Для регулярных выражений абстракция символов часто обескураживает многих программистов. Что касается характеристик плохой памяти, я пытаюсь сделать ее значимой с помощью классификации и ассоциации. Мы начинаем с одиночных символов один к одному, затем вводим подстроки многие ко многим, а затем строим расширенные регулярные выражения с помощью группировки, обратных ссылок и логической обработки.
В конце концов, придумайте обычный обычный вопрос на собеседовании: пожалуйста, напишите обычный, чтобы иметь дело с тысячными числами, например12345
заменить12,345
. Пожалуйста, попробуйте найти ответ самостоятельно, а не полагаться на поисковые системы :).
——Данная статья впервые опубликована в личном паблике, просьба указывать источник для перепечатки——
Наконец, приглашаю всех обратить внимание на мой официальный аккаунт и вместе учиться и общаться.