Понимание синтаксиса регулярных выражений JavaScript за один раз

внешний интерфейс GitHub JavaScript регулярное выражение

Эта статья является одной из серии статей на тему "Подкова·Regex", и в будущем будет создано больше тем.

Адрес гитхаба:GitHub.com/VE Эд Рин/hor…

Адрес блога (вёрстка статьи очень красивая):matiji.cn

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


Имя Юй называется Чжэнчжиси, а слово Юй называется Линцзюнь.

Regular ExpressionsВ переводе на китайский язык называются регулярными выражениями. Не знаю, кто перевел, звучит очень серьезно. кажется, переводится на通用表达式Он может лучше передать его суть, если вы не боитесь мечтать о Цюй Юане.

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

Нам нужно помнить три вещи:

Во-первых, регулярные выражения используются для извлечения текста.

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

В-третьих, синтаксис регулярных выражений не очень удобен для новичков.

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

Я также подготовил слоган для читателей, который должен заставить ваше сердце шевельнуться (понравиться), верно?

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

нормальные персонажи

Что такое обычные персонажи?

когда мы пишемaкогда мы имеем в видуa; когда мы пишемкогда мы имеем в виду.

'hello 😀 regex'.match(/😀/);
// ["😀", index: 6, input: "hello 😀 regex", groups: undefined]

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

начать и закончить

^персонаж на английском этоcaret, в переводе на китайский脱字符. Не спрашивайте, я не переводил. Это обычный метасимвол, который обычно представляет собой начало текста. говорят обычно, потому что, когда он находится в группе символов[^abc]смысл иначе.

Что такое начало текста? То есть, если это первый символ обычного тела, символ, следующий сразу за ним, должен быть первым символом соответствующего текста.

'regex'.match(/^r/);
// ["r", index: 0, input: "regex", groups: undefined]

Вопрос в том, если^Как насчет первого символа, который не является правильным?

'regex'.match(/a^r/);
// null

Итак, есть три вещи, на которые стоит обратить внимание:

  • Он должен быть первым символом обычного тела, когда он используется в качестве начального метасимвола соответствующего текста, иначе обычный символ недействителен.
  • Он соответствует местоположению, а не конкретному тексту.
  • В других правилах оно имеет другое значение.

$персонаж с^ровно наоборот. Он представляет собой конец текста и не имеет другого значения (имеет, но не в обычном теле). Опять же, это должен быть последний символ обычного тела.

'regex'.match(/x$/);
// ["x", index: 4, input: "regex", groups: undefined]

^а также$Особенность в том, что он соответствует позиции. Позиция не похожа на персонажа, она невидима, поэтому ее сложнее понять.

побег

теперь мы знаем$В соответствии с конечной позицией текста это метасимвол. Но если я хочу соответствовать$сам? Необходимость соответствовать знаку доллара не может быть более распространенной. Так что мы должны понизить его до простых людей.

\Обратная косая черта делает именно это.

'price: $3.6'.match(/\$[0-9]+\.[0-9]+$/);
// ["$3.6", index: 7, input: "price: $3.6", groups: undefined]

Приведенный выше пример немного не соответствует классу, а неклассовая часть игнорируется.

ты можешь думать\Также метасимвол, он следует за другим метасимволом, чтобы восстановить его первоначальное значение.

если есть два\Шерстяная ткань? Это бегство от самого себя. если их три\Шерстяная ткань? Забиваем на два раздела, чтобы понять. И так далее.

Обычным символам предшествует\Каков эффект? Сначала они представляют собой целое, затем нормальные символы после их экранирования становятся обычными символами.

Метасимвол с обратной косой чертой

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

Винить можно только отсутствие общепринятых символов в компьютерной сфере.

метасимвол имея в виду
\b соответствовать границе слова
\B соответствовать границе не слова
\d Совпадение с цифровым символом (цифрой)
\D соответствует нечисловому символу
\s соответствует пробельному символу (пробелу)
\S соответствует непробельному символу
\w соответствует букве или цифре или знаку подчеркивания (слову)
\W соответствует символу, отличному от буквы, цифры и символа подчеркивания

Вы такой умный, вы должны быть в состоянии увидеть это с первого взгляда, заглавные буквы представляют собой антонимы. Да, это так запоминается.

\b метасимвол

\bТакже соответствует позиции, а не символу. Позиция между словом и пробелом называется границей слова.

'hello regex'.match(/\bregex$/);
// ["regex", index: 6, input: "hello regex", groups: undefined]
'hello regex'.match(/\Bregex$/);
// null

Так называемая граница слов недействительна для других языков, таких как китайский.

'jiangshuying gaoyuanyuan huosiyan'.match(/\bgaoyuanyuan\b/);
// ["gaoyuanyuan", index: 13, input: "jiangshuying gaoyuanyuan huosiyan", groups: undefined]
'江疏影 高圆圆 霍思燕'.match(/\b高圆圆\b/);
// null

так\bПереведи, что есть^\w|\w$|\W\w|\w\W.

\d метасимвол

\dСопоставьте число, обратите внимание, что число здесь не относится к типу числа в JavaScript, потому что текст состоит из строк. Это относится к символам, которые представляют числа.

'123'.match(/\d/);
// ["1", index: 0, input: "123", groups: undefined]

метасимвол \s

\sСоответствует символу пробела.

Здесь нужно объяснить, что такое пробельный символ.

Символ пробела — это не пробел, а надмножество пробелов. Многие люди говорят, что это\f\n\r\t\vсумма которых\fподача формы,\nэто новая строка,\rвозврат каретки,\tгоризонтальная вкладка,\vпредставляет собой вертикальную вкладку. Это так?

'a b'.match(/\w\s\w/);
// ["a b", index: 0, input: "a b", groups: undefined]
'a b'.match(/\w\f\w/);
// null
'a b'.match(/\w\n\w/);
// null
'a b'.match(/\w\r\w/);
// null
'a b'.match(/\w\t\w/);
// null
'a b'.match(/\w\v\w/);
// null
'a b'.match(/\w \w/);
// ["a b", index: 0, input: "a b", groups: undefined]

Те, кто говорят, что это, очевидно, не сделало эксперимент. На самом деле, правильное написание空格\f\n\r\t\vСумма набора содержит пробел, но не игнорируйте его. Эх, так пробел записывается в регулярном выражении как空一格Ну да, это просто случайно.

Многие из этого набора являются непечатными символами, и предполагается, что только\nнаш старый друг. Так что, если вам не нужно различать пробелы и символы новой строки, то смело используйте\sБар.

\w метасимвол

\wСоответствует букве, цифре или символу подчеркивания. Зачем ставить их вместе? Подумайте о переменных правилах в JavaScript, в том числе во многих приложениях, где имена пользователей могут быть только этими тремя, поэтому их удобно объединять.

Однако следует отметить, что буквы относятся к 26 английским буквам, а остальные не работают.

'正则'.match(/\w/);
// null

отрицательный инь и ян

Если мы объединим прописные и строчные метасимволы с обратной косой чертой, мы сможем найти любой символ. Да ни для кого.

'@regex'.match(/[\s\S]/);
// ["@", index: 0, input: "@regex", groups: undefined]

Значение квадратных скобок не указано первым.

Дао Шэнъи

.Значение в регулярном выражении Xianfeng Daogu, которое соответствует любому одиночному символу, кроме новой строки.

Если текст не имеет новой строки, то.а также[\b\B]а также[\d\D]а также[\s\S]а также[\w\W]эквивалентны.

Если в тексте есть новая строка, то(.|\n)а также[\b\B]а также[\d\D]а также[\s\S]а также[\w\W]эквивалентны.

'@regex'.match(/./);
// ["@", index: 0, input: "@regex", groups: undefined]

квантификатор

Ранее мы подчеркивали, что метасимвол соответствует только одному символу. даже такой сильный, как.Он также соответствует только одному.

что соответствуетgooooogleДолжен ли регулярное выражение быть записан как/gooooogle/Шерстяная ткань?

Регулярно насмехается и презирает вас.

Если совпадающий шаблон имеет повторы, мы можем объявить, сколько раз он повторяется.

квантификатор имея в виду
? Повторить ноль или один раз
+ Повторить один или несколько раз, то есть хотя бы один раз
* Повторить ноль или более раз, то есть любое количество раз
{n} повторить n раз
{n,} Повторить n или более раз
{n,m} Повторить количество раз от n до m раз, включая n раз и m раз

Следует отметить три вещи:

  • ?Полезно для таких вещей, как сопоставление протокола http, например:/http(s)?/. В дополнение к тому, чтобы быть квантиделетом, он имеет другие значения в регулярных выражениях, которые будут упомянуты позже.

  • Мы привыкли к/.*/чтобы сопоставить какой-то текст, который не имеет для нас значения, его смысл若干除换行符之外的字符. Например, нам нужна информация о форматировании в обоих концах текста, неважно, что в середине, она пригодится. Но его производительность не является хорошей.

  • {n,m}Между ними не может быть пробелов, пробелы имеют смысл в регулярных выражениях.

Самое запутанное в квантификаторах: что они повторяют?

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

'gooooogle'.match(/go{2,5}gle/);
// ["gooooogle", index: 0, input: "gooooogle", groups: undefined]

Что произойдет, если квантификатор появится сразу после другого квантификатора?

'gooooogle'.match(/go{2,5}+gle/);
// Uncaught SyntaxError: Invalid regular expression: /go{2,5}+gle/: Nothing to repeat

Жадный режим и нежадный режим

Как упоминалось ранее, за квантификатором не может сразу следовать другой квантификатор, и он вот-вот получит пощечину 👋👋.

'https'.match(/http(s)?/);
// ["https", "s", index: 0, input: "https", groups: undefined]
'https'.match(/http(s)??/);
// ["http", undefined, index: 0, input: "https", groups: undefined]

Тем не менее, мое лицо так легко ударить?

внимательно следить?Назад?Это не квантификатор, а переключатель режимов, который переключает из жадного режима в нежадный режим.

Жадный режим — это режим по умолчанию в обычном режиме, который должен соответствовать как можно большему количеству текста в соответствии с установленными правилами. Поскольку в регулярке есть квантификаторы, количество повторений может быть интервалом, так что есть компромисс.

Сразу после квантификатора добавить?чтобы включить нежадный режим. Как спасти беду.

Дело в том,?За ним должен следовать квантификатор, иначе он сам станет квантификатором.

группа символов

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

'grey or gray'.match(/gr[ae]y/);
// ["grey", index: 0, input: "grey or gray", groups: undefined]

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

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

Затем группы символов представляют собой отдельный мир, и метасимволы не нужно экранировать.

'$'.match(/[$&@]/);
// ["$", index: 0, input: "$", groups: undefined]

Наконец, есть два символа, которые имеют особое значение в группах символов.

^Представляет отрицание в группе символов и больше не является позицией начала текста.

'regex'.match(/[^abc]/);
// ["r", index: 0, input: "regex", groups: undefined]

если я хочу^Шерстяная ткань? Как упоминалось ранее, побег.

-Первоначально обычный символ превратился в дефис в группе символов.

'13'.match(/[1-9]3/);
// ["13", index: 0, input: "13", groups: undefined]

Дефис означает, что диапазон соответствия находится между символами слева и справа от него.

Что, если я это сделаю?

'abc-3'.match(/[0-z]/);
// ["a", index: 0, input: "abc-3", groups: undefined]
'xyz-3'.match(/[0-c]/);
// ["3", index: 4, input: "xyz-3", groups: undefined]
'xyz-3'.match(/[0-$]/);
// Uncaught SyntaxError: Invalid regular expression: /[0-$]/: Range out of order in character class

Вы нашли что-нибудь? Есть только два типа символов, которые можно переносить через дефис: английские буквы и цифры. А английские буквы можно соединить с цифрами, а порядок английских букв сзади. это и покер1 2 3 4 5 6 7 8 9 10 J Q Kэто правда.

Захватывающие и не захватывающие группы

Мы уже знаем, что такое квантификатор, а также знаем, что квантификатор может повторять только непосредственно предшествующий ему символ.

Что, если я хочу повторить строку символов?

'i love you very very very much'.match(/i love you very +much/);
// null
'i love you very very very much'.match(/i love you v+e+r+y+ +much/);
// null

Это определенно невозможно. Пришло время раскрыть скобки.

'i love you very very very much'.match(/i love you (very )+much/);
// ["i love you very very very much", "very ", index: 0, input: "i love you very very very much", groups: undefined]

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

И по умолчанию можно зафиксировать результат сопоставления скобок.

регулярный захват

Теперь у нас есть требование, соответствующее<div>Этикетка.

'<div>hello regex</div>'.match(/<div>.*<\/div>/);
// ["<div>hello regex</div>", index: 0, input: "<div>hello regex</div>", groups: undefined]

это очень просто. Но что, если я хочу сопоставить любой тег, включая пользовательские теги?

'<App>hello regex</App>'.match(/<([a-zA-Z]+)>.*<\/\1>/);
// ["<App>hello regex</App>", "App", index: 0, input: "<App>hello regex</App>", groups: undefined]

В это время используется обычная функция захвата. Регулярный захват с использованием\数字, соответствующий содержимому, захваченному предыдущими круглыми скобками, соответственно. Эта захваченная ссылка также называетсяобратная ссылка.

Рассмотрим более сложный случай:

'<App>hello regex</App><p>A</p><p>hello regex</p>'.match(/<((A|a)pp)>(hello regex)+<\/\1><p>\2<\/p><p>\3<\/p>/);
// ["<App>hello regex</App><p>A</p><p>hello regex</p>", "App", "A", "hello regex", index: 0, input: "<App>hello regex</App><p>A</p><p>hello regex</p>", groups: undefined]

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

Нестандартный захват

'@abc'.match(/@(abc)/);
// ["@abc", "abc", index: 0, input: "@abc", groups: undefined]
RegExp.$1;
// "abc"

Вот так,RegExpзаключается в создании обычного конструктора. Если есть группа захвата, ее свойство экземпляра$数字Будет отображена соответствующая ссылка.

А если регуляров несколько?

'@abc'.match(/@(abc)/);
// ["@abc", "abc", index: 0, input: "@abc", groups: undefined]
'@xyz'.match(/@(xyz)/);
// ["@xyz", "xyz", index: 0, input: "@xyz", groups: undefined]
RegExp.$1;
// "xyz"

RegExpСсылка на конструктор показывает только последний обычный захват.

Существует также метод экземпляра строки, который также поддерживает обычные захваченные ссылки, т.е.replaceметод.

'hello **regex**'.replace(/\*{2}(.*)\*{2}/, '<strong>$1</strong>');
// "hello <strong>regex</strong>"

На самом деле, это наиболее часто используемый способ захвата ссылок.

захват именования

Это новое в ES2018.

использовать\数字Захват ссылок должен сохранять порядок групп захвата неизменным. Теперь разработчик может назвать группу захвата, и с именем ссылка будет более определенной.

'<App>hello regex</App>'.match(/<(?<tag>[a-zA-Z]+)>.*<\/\k<tag>>/);
// ["<App>hello regex</App>", "App", index: 0, input: "<App>hello regex</App>", groups: {tag: "App"}]

Внутри группы захвата добавьте?<key>, оно названо. использовать\k<key>синтаксис для ссылки на именованную группу захвата.

Разве это не просто?

Часто разработчики просто хотят обрабатывать определенные символы в регулярном выражении как единое целое. Группы захвата великолепны, но они выполняют дополнительные функции и определенно требуют дополнительного объема памяти и вычислительных ресурсов. Таким образом, регуляр имеет понятие группы без захвата.

'@abc'.match(/@(abc)/);
// ["@abc", "abc", index: 0, input: "@abc", groups: undefined]
'@abc'.match(/@(?:abc)/);
// ["@abc", index: 0, input: "@abc", groups: undefined]

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

Личное мнение: я думаю, что обычный дизайн захвата должен быть изменен, а не захват по умолчанию, плюс?:Захват после идентификации. Потому что чаще всего разработчикам не нужно захватывать, а добавлять лень?:логотип, будет небольшая потеря производительности.

ветвь

Иногда разработчикам нужно использовать в обычном或者.

'高圆圆'.match(/陈乔恩|高圆圆/);
// ["高圆圆", index: 0, input: "高圆圆", groups: undefined]

|от имени或者. Группа символов на самом деле представляет собой структуру с множественным выбором, но между ними есть существенные различия. Группа символов может соответствовать только одному символу в конце, а ветвь соответствует всем символам слева или всем символам справа.

Давайте посмотрим на пример:

'我喜欢高圆圆'.match(/我喜欢陈乔恩|高圆圆/);
// ["高圆圆", index: 3, input: "我喜欢高圆圆", groups: undefined]

потому что|Это разрезать левую и правую стороны пополам, а затем сопоставить левую или правую. Таким образом, приведенная выше регуляризация, очевидно, не может достичь желаемого эффекта. В это время необходимо что-то, чтобы сузить рамки ветки. Эй, вы, возможно, подумали о:

'我喜欢高圆圆'.match(/我喜欢(?:陈乔恩|高圆圆)/);
// ["我喜欢高圆圆", index: 0, input: "我喜欢高圆圆", groups: undefined]

Да, скобки.

утверждение нулевой ширины

Есть некоторые обычные метасимволы, они соответствуют не символам, а позиции. Например, упомянутый ранее^а также$.^означает, что эта позиция должна быть позицией начала текста.

Regular также имеет более продвинутый синтаксис для сопоставления позиций, который соответствует: что должно быть до или после этой позиции.

Что означает нулевая ширина? Это означает, что он соответствует позиции и не имеет ширины.

Что означает утверждение? Относится к суждению, которое утверждает, что должно или не должно быть до или после.

Утверждение положительного просмотра вперед нулевой ширины

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

Упреждающий просмотр относится к предварительному просмотру, а позиция утверждения обслуживает предыдущие правила.

Синтаксис прост: добавьте крайний левый в круглые скобки?=логотип.

'CoffeeScript JavaScript javascript'.match(/\b\w{4}(?=Script\b)/);
// ["Java", index: 13, input: "CoffeeScript JavaScript javascript", groups: undefined]

Вышеупомянутые совпадения - это четыре буквы, и эти четыре буквы должны соответствовать следующим условиям: следующее должно бытьScriptстрока иScriptСтрока должна быть концом слова.

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

Грубо говоря, я хочу сопоставить фрагмент текста, но за этим фрагментом текста сразу должен следовать другой определенный фрагмент текста. Утверждение положительного просмотра вперед нулевой ширины является граничным маркером, я хочу удовлетворить все предыдущие и последующие условия, но мне нужен только предшествующий текст.

Давайте рассмотрим другую ситуацию:

'CoffeeScript JavaScript javascript'.match(/\b\w{4}(?=Script\b)\w+/);
// ["JavaScript", index: 13, input: "CoffeeScript JavaScript javascript", groups: undefined]

Приведенный выше пример является более интуитивным, было сопоставлено утвердительное утверждение нулевой ширины.Scriptоднажды, позже\w+но все равно совпадаютScriptуспех, достаточно, чтобы объяснить его零宽характеристика. Он обслуживает правила, непосредственно предшествующие ему, и не влияет на последующие правила сопоставления.

Положительное ретроспективное утверждение нулевой ширины

Первое — смотреть вперед, второе — смотреть назад.

Синтаксис заключается в добавлении самого левого в круглые скобки?<=логотип.

'演员高圆圆 将军霍去病 演员霍思燕'.match(/(?<=演员)霍\S+/);
// ["霍思燕", index: 14, input: "演员高圆圆 将军霍去病 演员霍思燕", groups: undefined]

Регулярное выражение может иметь несколько утверждений:

'演员高圆圆 将军霍去病 演员霍思燕'.match(/(?<=演员)霍.+?(?=\s|$)/);
// ["霍思燕", index: 14, input: "演员高圆圆 将军霍去病 演员霍思燕", groups: undefined]

Утверждение отрицательного просмотра вперед нулевой ширины

Утверждение — это суждение о чем-то, а отрицание — суждение о том, что ничего нет.

Синтаксис заключается в добавлении самого левого в круглые скобки?!логотип.

'TypeScript Perl JavaScript'.match(/\b\w{4}(?!Script\b)/);
// ["Perl", index: 11, input: "TypeScript Perl JavaScript", groups: undefined]

Утверждение обратного просмотра отрицания нулевой ширины

Синтаксис заключается в добавлении крайних левых скобок?<!логотип.

'演员高圆圆 将军霍去病 演员霍思燕'.match(/(?<!演员)霍\S+/);
// ["霍去病", index: 8, input: "演员高圆圆 将军霍去病 演员霍思燕", groups: undefined]

модификатор

В дополнение к синтаксису тела регулярные выражения имеют несколько необязательных модификаторов шаблона.

Метод письма заключается в размещении модификатора на хвосте обычного субъекта. Например:/abc/gi.

g модификатор

gдаglobalаббревиатура от. По умолчанию регулярное выражение соответствует слева направо и останавливается до тех пор, пока результат совпадает.gМодификатор включает режим глобального сопоставления, находя все совпадающие результаты.

'演员高圆圆 将军霍去病 演员霍思燕'.match(/(?<=演员)\S+/);
// ["高圆圆", index: 2, input: "演员高圆圆 将军霍去病 演员霍思燕", groups: undefined]
'演员高圆圆 将军霍去病 演员霍思燕'.match(/(?<=演员)\S+/g);
// ["高圆圆", "霍思燕"]

я модификатор

iдаignoreCaseаббревиатура от. по умолчанию,/z/не может соответствоватьZ, поэтому иногда приходится писать:/[a-zA-Z]/.iМодификаторы могут игнорировать регистр глобально.

Во многих случаях нам все равно, является ли текст прописным, строчным или смешанным, этот модификатор по-прежнему очень полезен.

'javascript is great'.match(/JavaScript/);
// null
'javascript is great'.match(/JavaScript/i);
// ["javascript", index: 0, input: "javascript is great", groups: undefined]

м модификатор

mдаmultilineаббревиатура от. У этого модификатора есть определенный контекст, в котором он работает: его нужно комбинировать с^а также$Используйте вместе. по умолчанию,^а также$соответствует началу и концу текста, плюсmмодификаторы, их значение становится началом и концом строки.

`
abc
xyz
`.match(/xyz/);
// ["xyz", index: 5, input: "↵abc↵xyz↵", groups: undefined]
`
abc
xyz
`.match(/^xyz$/);
// null
`
abc
xyz
`.match(/^xyz$/m);
// ["xyz", index: 5, input: "↵abc↵xyz↵", groups: undefined]

у модификатор

Это новое в ES2015.

yдаstickyаббревиатура от.yмодификаторы имеют иgМодификаторы перекрывают функции, все они являются глобальными совпадениями. Итак, дело в том,stickyкак это понимать粘连Шерстяная ткань?

gМодификаторы не привередливы в еде, сопоставляют одно, а затем сопоставляют следующее, и нет требований к положению текста. ноyМодификатор требует, чтобы сопоставление выполнялось с начала текста, потому что оно включает глобальное совпадение, а следующий символ совпадающего текста является началом следующего текста. Это называется адгезией.

'a bag with a tag has a mag'.match(/\wag/g);
// ["bag", "tag", "mag"]
'a bag with a tag has a mag'.match(/\wag/y);
// null
'bagtagmag'.match(/\wag/y);
// ["bag", index: 0, input: "bagtagmag", groups: undefined]
'bagtagmag'.match(/\wag/gy);
// ["bag", "tag", "mag"]

Кто-то, должно быть, нашел что-то хитрое: вы не сказалиyЯвляется ли модификатор глобальным соответствием? Глядя на приведенный выше пример, одинyКак модификатор может использовать метод match, а не глобальное совпадение?

Эх, тут длинная история.

Короче говоря, это включает в себяyКакова природа модификаторов. Он имеет две сущности:

  • Глобальный матч (пока не спешите бить меня).
  • из текстаlastIndexпозицию для начала нового матча. что такое lastIndex? Это атрибут регулярного выражения, если это глобальное совпадение, оно используется для обозначения начальной точки следующего совпадения. В этом суть адгезии.

Не знаю, нашли ли вы что-нибудь:lastIndex является свойством регулярного выражения. Метод match в приведенном выше примере работает со строками, а атрибут lastIndex отсутствует.

const reg = /\wag/y;
reg.exec('bagtagmag');
// ["bag", index: 0, input: "bagtagmag", groups: undefined]
reg.exec('bagtagmag');
// ["tag", index: 3, input: "bagtagmag", groups: undefined]
reg.exec('bagtagmag');
// ["mag", index: 6, input: "bagtagmag", groups: undefined]

Заменяем его на обычный метод exec, выполняем несколько раз, меняется обычный lastIndex, меняется и результат сопоставления. Это определенно глобальный матч.

модификатор s

Это новое в ES2018.

sнетdotAllаббревиатура от.sмодификатор быть и.При использовании по умолчанию.Соответствует любому одиночному символу, кроме символа новой строки, но он еще недостаточно мощный, чтобы делать все, поэтому обычный просто дает ему зависнуть.

sРоль модификатора состоит в том, чтобы сделать.Может соответствовать любому одиночному символу.

sдаsinglelineаббревиатура от.

`
abc
xyz
`.match(/c.x/);
// null
`
abc
xyz
`.match(/c.x/s);
// ["c↵x", index: 3, input: "↵abc↵xyz↵", groups: undefined]

у модификатор

Это новое в ES2015.

uдаunicodeаббревиатура от. Некоторые символы Юникода длиннее одного байта, и регулярное выражение не распознает их правильно.uМодификаторы используются для решения этих менее распространенных случаев.

'𠮷'.match(/^.$/);
// null
'𠮷'.match(/^.$/u);
// ["𠮷", index: 0, input: "𠮷", groups: undefined]

𠮷читать,а такжесиноним.

Знания автора о Unicode все еще невелики, поэтому я не буду здесь их расширять.


Эта статья является одной из серии статей на тему "Подкова·Regex", и в будущем будет создано больше тем.

Адрес гитхаба:GitHub.com/VE Эд Рин/hor…

Адрес блога (вёрстка статьи очень красивая):matiji.cn

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

Краткий обзор тем регулярных выражений

👉грамматика

👉метод

👉двигатель