Используйте родной язык, чтобы легко получить регулярный (ниже)

JavaScript

предисловие

Эта статьяЛегко получить обычный jsПродолжение статьи, предлагаю сначала прочитать эту статьюЛегко получить обычный js, (обычные основы хороши, и большие парни могут их игнорировать), в статье могут быть недостатки, и я надеюсь, что все смогут указать это в области комментариев, и все смогут учиться вместе (моя собственная тарелка ковыряет ноги), эта статья тоже с перерывами близко к половине Я только что закончил писать его за месяц (в основном потому что был занят, а позже я встретил технический текст двойного раздела, поэтому я написал эссе об обучении перерисовке и переплавке вместе), и, наконец, давайте поговорим о эту гидрологию вместе! Если эта статья была вам полезна, вы можете подписаться на мой паблик, давайте изучать фронтенд вместе😄

выберите совпадение

Выбор совпадений в логических операциях, подобных JavaScript||выражатьЭто означает, что в обычном JS есть соответствующий режим, называемыйвыберите совпадение

использует|, его синтаксисx|yНачнем с простого случая:

let str='abcd';
let reg=/a|ab/;
let res=str.match(reg);
console.log(res)//["a", index: 0, input: "abcd", groups: undefined]

Порядок сопоставления выбораслева направо, пока не будет найдено совпадение, игнорируя совпадение справа (даже если оно дает лучшее совпадение).

Вышеприведенное соответствует, даже еслиabБолее подходящий, но все еще только совпаденияa.

Еще один 🌰, который мы хотим использоватьвыберите совпадениечтобы соответствовать символу, толькоabилиcd. Над кодом:

let reg=/^ab|cd$/;
console.log(reg.test('ab'));//true   ab或者是cd中的一个,所以为true
console.log(reg.test('cd'));//true   ab或者是cd中的一个,所以为true
console.log(reg.test('abc'));//true  以ab开头,所以为 true
console.log(reg.test('abd'));//true  以 a开头,中间b或者c,以d结尾,所以为true
console.log(reg.test('acd'));//true  以 a开头,中间b或者c,以d结尾,所以为true
console.log(reg.test('abcd'));//true 以ab开头 或者 以cd结尾 ,所以为true
console.log(reg.test('bcd'));//true  以cd 结尾,所以为true
console.log(reg.test('bacd'));//true 以cd 结尾,所以为true

Результат приведенного выше вывода не очень неожиданный, нам нужен результатabилиcdбудет выводитьtrue, остальныеfalse, Причиной вышеизложенного является проблема приоритета.

Использовать напрямую x|yТо есть сопоставление выбора, если символ для сопоставления выбора находится вДва или более, будет очень грязная проблема с приоритетом, какие там правила работы в регулярке, автор еще не разобрался (надеюсь обсудить и узнать с вами в комментариях), поэтому пользуюсьПри выборе соответствия он обычно не используется сам по себе.Обычно при выборе соответствия используются круглые скобки для группировки группы., скобки могут изменить приоритет, как его изменить, давайте посмотрим вниз

групповое сопоставление

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

这是一个 小数的数学运算题
1+2+(2*3)
=1+2+6
=3+6
=9

Затем давайте рассмотрим проблему использования группового сопоставления для изменения приоритета сопоставления выбора.

let reg=/^(ab|cd)$/;
console.log(reg.test('ab'));//true
console.log(reg.test('cd'));//true
console.log(reg.test('abc'));//false
console.log(reg.test('abd'));//false
console.log(reg.test('abcd'));//false
console.log(reg.test('bcd'));//false
console.log(reg.test('bacd'));//false

В коде используйте()группировка, изменение приоритета, совпадение в первую очередьab|cd, а потом^а также$.

Сгруппированные снимки и ссылки

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

let str = '2020-09-29';
let reg = /(\d{4})-(\d{2})-(\d{2})/;
let res=reg.test(str);  
console.log(res);//true
console.log("第一个分组匹配到的字符",RegExp.$1);
console.log("第二个分组匹配到的字符",RegExp.$2);
console.log("第三个分组匹配到的字符",RegExp.$3);

🌰 Используйте группировку в регулярке, чтобы сделать демо замены созданного формата даты

Когда дело доходит до замены, каждый обязательно вспомнит то, о чем мы говорили в предыдущей статье.replace()метод, есть два способа его использования в сочетании с группировкой для замены даты: 👇👇👇

метод первый:

let str = '现在北京时间2020:09:29';
let reg = /(\d{4}):(\d{2}):(\d{2})/;
str = str.replace(reg,'$1-$2-$3') 
console.log(str)//现在北京时间2020-09-29

Способ второй:

let str = '现在北京时间2020:09:29';
let reg=/:/g;
str = str.replace(reg,'-');
console.log(str)//现在北京时间2020-09-29

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

Причина очень проста, ведь закономерность первого способа/(\d{4}):(\d{2}):(\d{2})/Что сопоставляется, так это наш общий формат события, даже в очень длинной строке, только такой формат события может быть ею захвачен, а регулярность во втором способе/:/gЧто может быть захвачено, так это все персонажи в:, а также будет заменен на-, а в очень длинном символе используйте символ:Есть много мест, которые будут заменены на-.

именованная группа захвата

Именованная группа захвата, на просторечии, чтобы назвать группу захвата, один из ее синтаксиса(?<name>...), что больше, чем у обычных групп в группах, о которых мы говорили выше.?<name>, на самом деле,nameТочно так же, как имена переменных, которые мы обычно используем.

let str="现在是北京时间2020-09-30";
let reg=/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
//exec() 和 match() 方法返回的匹配结果数组上多了一个 groups 属性,里面存放着每个命名分组的名称以及它们匹配到的值,
let res=str.match(reg).groups;
console.log(res);

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

Сопоставление групп не фиксируется

(?:)Только совпадение без захвата;

Иногда группировку без захвата можно использовать только для целей группировки и когда захват не требуется, например:

let str = '2020-09-29';
let reg = /(?:\d{4})-(\d{2})-(\d{2})/
console.log(reg.test(str));
console.log("RegExp.$1:",RegExp.$1);
console.log("RegExp.$2:",RegExp.$2);

в символах2020-09-29Используйте обычные/(?:\d{4})-(\d{2})-(\d{2})/соответствовать,reg.test(str)Напечатанный результатtrue, указывая на то, что символы соответствуют обычным условиям сопоставления,RegExp.$1Напечатанный результат09, потому что первая группировка(?:\d{4})Выполняется только сопоставление, захват не выполняется.

Упреждающий взгляд вперед (прогнозирующий)

Упреждающий просмотр (также называемый предварительным просмотром), который включает в себяПоложительный позитивный прогноза такжеположительный отрицательный взгляд впередДва пути. Сначала вы можете вспомнить здесь, а мы поговорим об этом подробно позже.

Положительный позитивный прогноз

Один из синтаксисов положительного положительного взгляда вперед:(?=pattern)где персонажи внутриpatternзначитПолучить этот символ, но не сопоставлять его (только как условное ограничение при сопоставлении, не будет выводить результат сопоставления), не кажется ли это немного запутанным, это трудно понять, давайте поговорим прямо по коду

let reg=/\d+(?=元)/g;
console.log(reg.test("399元"));//true
console.log("399元".match(reg))//399

в коде/\d+(?=元)/gСпичкиодно или несколько чисел, за которыми следует肯定следовать за однимформат: 1234 юаней (то есть число должно сопровождаться юанью), а штатный захват - только предыдущий номер, предварительно проверенныйне захвачен

let reg=/\d+(?=元)/g;
console.log(reg.test("399元"));//true
console.log("399元".match(reg))//399
console.log(reg.test("499磅"));//false  
console.log("499磅".match(reg))//null

в коде/\d+(?=元)/gПоложительная аффирмация (? в скобках сопровождается =) предварительная проверка, поэтому строка399元Соблюдение правил, соответствующих регулярному выражению, а именноreg.test("399元")Результатtrue , "399元".match(reg)Результат399; а в кодеreg.test("499磅"), конец после числаслово не соответствует/\d+(?=元)/gпредварительно проверено,такreg.test("499磅")Результатfalse, "499磅".match(reg)Результатnull, то есть нет совпадающих результатов.

положительный отрицательный взгляд вперед

Положительная отрицательная предварительная проверка прямо противоположна положительной положительной предварительной проверке, положительная положительная предварительная проверка (?=pattern)Положительная отрицательная предварительная проверка(?!pattern), обсуждалось ранее/\d+(?=元)/gСпичкиЭто должно быть после номера,Это/\d+(?!元)/gКакой матч, не волнуйся, посмотри вниз;

let reg=/\d+(?!元)/g;
console.log("399元".match(reg))//39
console.log("3990元".match(reg))//399
console.log("499磅".match(reg))//499
console.log("599¥".match(reg))//599

(?!元)положительный отрицательный взгляд впередэтот символ (не метасимвол), затем/\d+(?!元)/gЧто можно захватить, так этоСимвол, который не является мета после числа; Так вы считаете результаты кода на строках 4 и 5 в приведенном выше коде то, что вы ожидали, но результаты второй и третьей строк не совсем понятны, почему получается вторая строка39, вместо399, потому что если это 399, следующее число, вот отрицательная предварительная проверка, символ после цифры, а не, так что можно захватить39, символы после него9,нет.

Опираясь на основу прямой предварительной проверки, давайте поговорим об обратной предварительной проверке ⬇⬇⬇⬇⬇⬇⬇

Обратный просмотр вперед (заглянуть назад)

Выше мы говорили оПрямой поискон жепредвидение, вы можете комбинировать приведенный выше код case и попытаться разобраться внимательно.Прежде всего, будь то прямая предварительная проверка или обратная предварительная проверка (назад), все ониВ качестве условного ограничения при сопоставлении результат сопоставления не будет выведен. В случае кода положительного положительного просмотра вперед,/\d+(?=元)/gдаЭтот китайский иероглиф служит разделительной точкой,этот китайский иероглифПереднийЭто число, то есть число после числа должно быть,такой жеположительный отрицательный взгляд впередТо же самое справедливо. Является ли это более глубоким пониманием положительной предварительной проверки? ! (Этот текст в основном размещен здесь, чтобы каждый мог сравнить и понять предварительную проверку вперед и предварительную проверку назад)

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

обратный позитивный просмотр вперед

Обратный положительный просмотр вперед. Один из его синтаксисов:(?<=pattern) где персонажи внутриpatternзначитПолучить этот символ, но не сопоставлять его (только как условное ограничение при сопоставлении, не будет выводить результат сопоставления)

let reg=/(?<=¥)\d+/g;
console.log("¥399".match(reg))//399
console.log("¥3990".match(reg))//3990
console.log("$499".match(reg))//null

То есть число передэтот персонаж, но персонажОн только получает и не выводит совпадающий результат, поэтому вывод кода во второй строке:399, вывод третьей строки кода3990, символы в четвертой строке$499не перед номером, то есть условие совпадения не выполняется (знак, предшествующий цифре, должен бытьчисло), поэтому ни один результат не был сопоставлен.

обратный отрицательный поиск

Обратный отрицательный просмотр вперед. Один из его синтаксисов:(?<!pattern) где персонажи внутриpatternзначитПолучить этот символ, но не сопоставлять его (только как условное ограничение при сопоставлении, не будет выводить результат сопоставления)

let reg=/(?<!¥)\d+/g;
console.log("¥399".match(reg))//99
console.log("¥3990".match(reg))//990
console.log("$499".match(reg))//499

Обычный/(?<!¥)\d+/gПолучите перед номером, а неномер, код во второй строке"¥399".match(reg)Что получается, так это то, что перед числом неЦифры (немного вокруг, постарайтесь разобраться внимательно),99предшествуют цифры3,нетСоблюдение условий согласования, результатом вывода является99, третья строка такая же, четвертая строка кода"$499".match(reg)средний, цифровой499Предыдущие символы$,нет, поэтому условие совпадения499.

Жадное сопоставление и нежадное сопоставление

Сложность: жадный режим/ленивый режим (не жадный)

Жадный режим - при успешном сопоставлении попытайтесь сопоставить как можно больше (он более жадный и хочет больше 😄)

Ленивый режим - при успешном сопоставлении старайтесь сопоставлять как можно меньше (это ленивый и соответствует как можно меньшему количеству совпадений)

// 贪婪匹配
let greedy = 'aaaaaa'.match(/a+/g);
console.log('greedy',greedy );
// 非贪婪匹配
let lazy = 'aaaaaa'.match(/a+?/g);
console.log('lazy',lazy);

В приведенном выше коде'aaaaaa'.match(/a+/g)жадный, где обычный/a+/gнаходится в глобальном, соответствующие символыa один или несколько раз, исходя из успешного сопоставления, пытаться сопоставить столько раз, сколько возможно, пока не произойдет совпадение, поэтому результат сопоставления["aaaaaa"], Однако'aaaaaa'.match(/a+?/g)является нежадным (он же ленивым), хотя только еще одним?, но результаты сопоставления совсем другие,?Значит этоноль или один раз, добавить после жадного режима?Он становится ленивым, то есть будет совпадать как можно меньше, то есть в процессе сопоставления, как только результат совпадет, сопоставление будет прекращено (потому что оно ленивое 罒ω罒).

историческая статья

  1. Изучайте перерисовку и перекомпоновку вместе | Технические документы Nuggets - Специальное предложение по двойным секциям
  2. Использование родного языка для простого получения обычных правил (Часть 1)
  3. Принцип механизма сборки мусора js вам понятно объяснил
  4. Приближается ES11, почему бы вам не зайти и не посмотреть?
  5. Поймите область действия js и цепочку областей видимости за считанные секунды
  6. Все необходимые команды git находятся здесь