Самая полная сводка знаний по фронтенд-регулярности (достаточно научиться ее собирать)

регулярное выражение

Карта мозга из этой статьи скоро появится

1. Регулярное понимание

1.1 Что такое обычное

регулярное выражение: RegExp (правило обработки строк)

  • использовал к"обрабатывать строки"Правило (может обрабатывать только строки, а не строки не может обрабатывать, но вы можете использоватьtoString()Метод становится строкой, хахахаха, ты что, запутался, давай каштан, чтобы понять)
  • Он"правило": вы можете проверить, соответствует ли строка определенному правилу (проверка), или вы можете захватить содержимое строки, которая соответствует правилу (exec/match...)

1.2 Предварительный вид штатного

Ниже приведен пример использования регулярного выражения для проверки строки! Давайте сначала кратко рассмотрим формат.Если вы читаете статью, значит, вы впервые столкнулись с регулярными выражениями.Прочитав следующую статью, вы сможете легко понять этот пример.

let str = 'good';
let reg = /\d+/;
reg.test(str);  //false

str = '2020-04-09';
reg.test(str); //true

2. Пишите регулярные выражения

2.1 Как создать

2.1.1 Как создавать литералы

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

let reg1 = /\d+/;

2.1.2 Создание шаблона конструктора

Используйте обычные объектыnewспособ, записанный в виде строки

//说明,字符串中直接`\d`是输出的d,因此需要使用`\`转义一下,
let reg2 = new RegExp('\\d+');

Независимо от того, какой из вышеперечисленных методов используется для создания, вы получаете тип данных объекта. Хотя reg1 и reg2 имеют одинаковые правила, ноreg1!==reg2, на самом деле адреса кучи памяти у них разные. (Это предполагает знание типов данных в JS, те, кто не понимает, могут просмотреть!)

2.2 Состав регулярных выражений

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

2.2.1 Метасимволы

  • Метасимвол квантификатора: установите количество вхождений
метасимвол имея в виду
* от нуля до многих раз
+ от одного до многих раз
? от нуля до одного
{n} n раз
{n,} п во много раз
{n,m} от n до m раз
  • Специальные метасимволы: одиночные или объединенные для представления особых значений
метасимвол имея в виду
\ escape-символ
. Любой символ, кроме \n (новая строка)
^ какой метасимвол начинается с
$ на какой метасимвол заканчивается
\n новая линия
\d Число от 0 до 9 (включая 0 и 9)
\D Разделить число от 0 до 9
\w Любой символ среди цифр, букв и знаков подчеркивания
\s Пробельный символ (включая пробелы, табуляции, переводы форм)
\t Символ табуляции (одна клавиша TAB, четыре пробела)
\b соответствовать границе слова
x|y символ в x или y
[xyz] символ в x или y или z
[^xy] любой символ, кроме x и y
[a-z] Укажите любой символ в диапазоне от a до z
[^a-z] Отрицание предыдущего «не»
() группировка символов в регулярном выражении
(?:) только совпадение без захвата
(?=) Прямой поиск
(?!) обратный поиск
  • Обычные метасимволы: представление собственного значения

    • /name/Этот регулярный должен соответствовать'name'

2.2.2 Модификаторы: вне регулярного выражения/j/g

модификатор имея в виду
i(ignoreCase) Игнорировать соответствие регистра
m(multiline) Это может быть многострочное соответствие
g(global) глобальное совпадение
u(Unicode) Используется для правильной обработки символов Юникода размером больше \uFFF.
y(sticky) адгезия
s(dotAll) Сделать '.' совпадающим с любым символом, включая \n\r

отступить, отступить, отступить

2.3 Подробное объяснение общих метасимволов

2.3.1 ^ $

Когда мы пишем регулярные выражения, чтобы быть более строгими, мы обычно добавляем эти два метасимвола, а затем пишем наши правила между ними (если мы не пишем ^$, правила, которые мы пишем, иногда имеют значения Неожиданные вещи, ха-ха, не надо не волнуйтесь, делайте это шаг за шагом. Когда я введу {n, m}, это будет объяснено вместе с ним)

  • ^ с каким метасимволом
  • какой метасимвол заканчивается на $
  • ^/$ Оба не совпадают: строка содержит содержимое, соответствующее правилам.
  • ^/$ Оба добавляются для соответствия: строка может быть только тем содержимым, которое соответствует правилам.
//匹配的是:以数字开头的字符串
let reg = /^\d/;
console.log(reg.test('name'));   //false
console.log(reg.test('2020name'));  //true
console.log(reg.test('name2020'));   //false
//匹配的是:以数字结尾的字符串
let reg = /\d$/;
console.log(reg.test('name')); //false
console.log(reg.test('2020name'));  //false
console.log(reg.test('name2020'));  //true
// ^/$ 两个都不加匹配的是:字符串中包含符合规则的内容即可
let reg1 = /\d/;
console.log(reg1.test('as2')); //true
//^/$ 两个都加匹配的是:字符串只能是和规则一致的内容
let reg2 = /^\d$/
console.log(reg2.test('as2')); //false
console.log(reg2.test('22')); //false
console.log(reg2.test('2')); //true

2.3.2 \

  • Эскейп-символы, он может бессмысленное превращать в осмысленное, а может и осмысленное менять на бессмысленное (вроде удалось вас запутать, ха-ха, например, я все понимаю)
//‘.’ 是代表除换行符之外的任意字符,而不是小数点
let reg = /^2.3$/;
console.log(reg.test('2.3')); //true
console.log(reg.test('2@3')); //true
console.log(reg.test('23')); //false

//现在我们把‘.’变为一个普通的小数点(使用到的就是\)
let reg = /^2\.3$/;
console.log(reg.test('2.3')); //true
console.log(reg.test('2@3')); //false

2.3.3 x|y

  • x или y: прямой x|y будет иметь проблему с приоритетом, обычно используемую со скобками для группировки, потому что скобки изменяют приоритет обработки => скобки: группировка
//匹配的是:以18开头或者以29结尾的都可以,以1开头以9结尾,8或2都可以,所以不加括号怎么理解都可以
//以下的匹配结果都为true
let reg = /^18|29$/;
console.log(reg.test('18'));
console.log(reg.test('29'));
console.log(reg.test('129'));
console.log(reg.test('189'));
console.log(reg.test('1829'));
console.log(reg.test('182'));
//以上不加括号我们可以有很多理解方式都是对的,但是我们加上括号,就不可能想上面那样理解了;
//匹配的是:18或者29中的一个,其余都是false
let reg = /^(18|29)$/;
console.log(reg.test('18'));
console.log(reg.test('29'));
console.log(reg.test('129'));
console.log(reg.test('189'));

2.3.4 []

  • Символы в скобках"в общем"Все представляют свой собственный смысл (будут размагничиваться, устраняя собственный смысл)
  • Значение \d в квадратных скобках по-прежнему 0-9, это не размагничено
  • [18]: представляет либо 1, либо 8.
  • [10-29]: представляет 1 или 9 или 0-2
//下面的‘.’就是小数点的意思
let reg = /^[.]+$/;
//匹配的含义是:只能是@或者+的
let reg = /^[@+]$/;
console.log(reg.test('@')); //true
console.log(reg.test('+')); //true
console.log(reg.test('@@')); //false
console.log(reg.test('@+')); //false
//匹配的含义是:\d还是代表0-9
let reg = /^[\d]$/;
console.log(reg.test('9')); //true
console.log(reg.test('\\')); //false
console.log(reg.test('d')); //false
//匹配的含义是:1或者8
let reg = /^[18]$/;
console.log(reg.test('1')); //true
console.log(reg.test('8')); //true
console.log(reg.test('18')); //false
//匹配的含义是:1或者0-2或者9
let reg = /^[10-29]$/;
//匹配的含义是:1或者0-2或者9或'('或')'
let reg = /^[(10-29)]$/;

2.3.5 {n,m}

  • Он представляет от n до m вхождений предыдущего метасимвола

    В следующем примере вне диапазона без ^$ возвращает true, но при использовании exec для захвата захватываются максимум 4 (эта проблема самая большая путаница, когда я учусь, если вы не знаете, как добавить Если вы добавите начальный и конечный символы, я всегда думаю, что это {n,m} бесполезно, когда оно выходит за пределы диапазона, ха-ха)

//这个正则匹配的是数字出现2到4次即可,明显第三个超出了,应该返回false,但是结果却是true,但是加上^$ 就不一样了
let reg = /\d{2,4}/;
reg.test('1');  //false
reg.test('14'); //true
reg.test('123456'); //true
//加上^$ 之后的结果:这个就代表只能有2-4位数字,超过就多余,而上一个匹配的是只有字符串中出现2-4次即可,因此加上^$ 更加严谨
let reg = /^\d{2,4}$/;
reg.test('1'); //false
reg.test('14'); //true
reg.test('123456'); //false

2.3.6 Группирующая роль

  • 1. изменить приоритет по умолчанию;
  • 2. Групповой захват;
  • 3. Групповые ссылки
//第一个作用:提升优先级,reg1可以匹配的比reg2的多,这个作用在上面已经说过了,这里就不再详细写
let reg1 = /^18|29$/;
let reg2 = /^(18|29)$/ 
//第二个作用:使用exec捕获的时候不仅可以得到整个大正则的结果,也会分别拿到每一个分组内的
let reg1 =/^([1-9]\d{5})((19|20)\d{2})(0[1-9]|10|11|12)(0[1-9]|[1-2]\d|30|31)\d{3}(\d|x)$/i;
//第三个作用:第一位是a-z的字母,分组1,;第二位也是a-z的字母,分组2;第三位\2是和第二个分组出现一模一样的内容...
let reg1 =/^([a-z])([a-z]\2\1)$/

2.3.7 Именование группы (присвоение имени группе)?

let str = '132123201203200000';
let reg = /^(?<A>[1-9]\d{5})(?<B>(19|20)\d{2})(?<C>0[1-9]|10|11|12)(?<D>0[1-9]|[1-2]\d|30|31)\d{3}(\d|x)$/i;
let res = reg.exec(str);
console.log(res);
console.log(res.groups.B);//可以直接拿到B组的内容

2.3.8 Пять функций вопросительных знаков в регуляризации

  • 1. Левая сторона вопросительного знака является метасимволом, не являющимся квантификатором: сама представляет собой метасимвол квантификатора, который появляется от нуля до одного раза;
  • 2. Левая часть вопросительного знака — метасимвол квантификатора: отменить жадность при захвате;
    1. (?:): только совпадение без захвата;
  • 4.(?=): предварительная проверка вперед;
    1. (?!) Отрицательный прогноз

2.4 Часто используемые регулярные выражения

2.4.1 Подтвердить номер мобильного телефона

правило:

  • 11 бит
  • Первый номер 1
  • Вторая цифра - любая из цифр 3-9
let reg = /^1[3-9]\d{9}$/;
console.log(reg.test('13245678945')); //true
console.log(reg.test('1324567895'));  //false
console.log(reg.test('12245678945'));  //false

2.4.2 Убедитесь, что это правильный номер

правило:

  • Можно начинать с +-
  • Целые биты:
    • Если это одна цифра, это может быть любое число от 0 до 9;
    • Если он многозначный, первая цифра не может быть 0;
  • Десятичный знак: если есть десятичный знак, то после запятой есть хотя бы одна цифра, или десятичного знака нет.
let reg = /^[+-]?(\d|[1-9]\d+)(\.\d+)?$/;
console.log(reg.test('0.2')); //true
console.log(reg.test('02.1'));  //false
console.log(reg.test('20.'));  //false

2.4.3 Подтверждение пароля

правило:

  • 6-16 состав
  • Должен состоять из цифр и букв
let reg = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[\d(a-z)(A-Z)]{6,16}$/;

2.4.4 Подтвердите настоящее имя

правило:

  • должно быть на китайском
  • Длина имени 2-10 цифр
  • Возможны переводы: · Китайские иероглифы

Дополнение: Как набрать точку посередине: в китайском штате клавиша под ESC может

let reg = /^[\u4E00-\u9FA5]{2,10}(·[\u4E00-\u9FA5]{2,10})?$/;

2.4.5 Проверка электронной почты

правило:

  • Имя почтового ящика состоит из нескольких частей «цифровая буква подчеркивания-.», но -/. не может стоять последовательно или начинаться с \w+((-\w+)|(.\w+))*;
  • За @ могут следовать цифры и буквы, а также могут появляться несколько цифр @[A-Za-z0-9]+ ;
  • Дополнение к имени после @: мультидоменное имя .com.cn доменное имя предприятия (.|-)[A-Za-z0-9]+)*
  • .com/.cn и другие доменные имена .[A-Za-z0-9]+
let reg = /^\w+((-\w+)|(\.\w+))*@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/

2.4.6 Проверка идентификационного номера

правило:

  • 18
  • Последняя цифра - это цифра или X
  • В топ-6 входят провинции, города и уезды.
  • Последние четыре цифры - год
  • Последние два месяца 01-12
  • Последние два дня 01-31
  • последние четыре
  • Последняя цифра: X или число
  • Предпоследняя цифра: Чет: Женский Нечетный: Мужской Роль группировки скобок: групповой захват может не только собирать большую регулярную совпадающую информацию, но и захватывать содержимое каждой небольшой группы отдельно.
let reg =/^([1-9]\d{5})((19|20)\d{2})(0[1-9]|10|11|12)(0[1-9]|[1-2]\d|30|31)\d{3}(\d|x)$/i;

2.5 Проверка страницы регистрации обычным письмом

2.5.1 Макет

Я использую макет начальной загрузки (кхм, нам нужно быть только старшим инженером CV, чтобы завершить это, хахахаха)

  • Загрузите пакет начальной загрузки в файле проекта, вы можете загрузить его непосредственно с официального сайта или использовать команду для загрузки в среде узла.npm i bootstrap
  • Вставьте CSS в пакет, который вы только что загрузили, на страницу.<link rel="stylesheet" href="node_modules/bootstrap/dist/css/bootstrap.min.css">
  • Перейдите на официальный сайт бутстрапа, чтобы найти нужную структуру и скопировать ее на свою страницу (примечание: на официальном сайте бутстрапа упоминалось, что мы помещаем все содержимое в контейнер контейнера, поэтому сначала добавьте div с именем класса снаружи)
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="node_modules/bootstrap/dist/css/bootstrap.min.css">
    <style>
        .container {
            padding: 0;
            width: 300px;
        }

        .form-text {
            color: red !important;
        }
    </style>
</head>

<body>
    <section class="container">
        <form>
            <div class="form-group">
                <label>真实姓名</label>
                <input type="text" class="form-control" id='userNameInp'>
                <small class="form-text text-muted" id='userNameTip'></small>
            </div>
            <div class="form-group">
                <label>邮箱</label>
                <input type="email" class="form-control" id='userEmailInp'>
                <small class="form-text text-muted" id='userEmailTip'></small>
            </div>
            <div class="form-group">
                <label>电话</label>
                <input type="text" class="form-control" id='userPhoneInp'>
                <small class="form-text text-muted" id='userPhoneTip'></small>
            </div>
            <div class="form-group">
                <label>密码</label>
                <input type="password" class="form-control" id='userPassInp'>
                <small class="form-text text-muted" id='userPassTip'></small>
            </div>
            <div class="form-group">
                <label>确认密码</label>
                <input type="password" class="form-control" id='userPassConfirmInp'>
                <small class="form-text text-muted" id='userPassConfirmTip'></small>
            </div>
            <button type="button" class="btn btn-primary" id='submit'>提交</button>
        </form>
    </section>
</body>

</html>

2.5.2 JS-валидация

  • Все поля должны быть заполнены;
  • Формат ввода должен соответствовать требованиям;
  • Проверьте, когда мышь покидает текстовое поле;
  • Также проверьте, когда нажата кнопка отправки;
let reginModule = (function () {
    let query = function (selector) {
        return document.querySelector(selector);
    }
    let userNameInp = query('#userNameInp'),
        userNameTip = query('#userNameTip'),
        userEmailInp = query('#userEmailInp'),
        userEmailTip = query('#userEmailTip'),
        userPhoneInp = query('#userPhoneInp'),
        userPhoneTip = query('#userPhoneTip'),
        userPassInp = query('#userPassInp'),
        userPassTip = query('#userPassTip'),
        userPassConfirmInp = query('#userPassConfirmInp'),
        userPassConfirmTip = query('#userPassConfirmTip'),
        submit = query('#submit');

    // 姓名验证 trim() 去除字符串的首尾空格
    let checkName = function checkName() {
        let val = userNameInp.value.trim(),
            reg = /^[\u4E00-\u9FA5]{2,10}(·[\u4E00-\u9FA5]{2,10})?$/;
        if (val.length === 0) {
            userNameTip.innerHTML = '真实姓名不能为空';
            return false;
        }
        if (!reg.test(val)) {
            userNameTip.innerHTML = '不符合姓名格式';
            return false;
        }
        userNameTip.innerHTML = '';
        return true;
    };
    //EMAIL
    let checkEmail = function checkEmail() {
        let val = userEmailInp.value.trim(),
            reg = /^\w+((-\w+)|(\.\w+))*@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/;
        if (val.length === 0) {
            userEmailTip.innerHTML = '邮箱不能为空';
            return false;
        }
        if (!reg.test(val)) {
            userEmailTip.innerHTML = '邮箱格式不正确';
            return false;
        }
        userEmailTip.innerHTML = '';
        return true;
    };
    // 手机号
    let checkPhone = function checkPhone() {
        let val = userPhoneInp.value.trim(),
            reg = /^1[3-9]\d{9}$/;
        if (val.length === 0) {
            userPhoneTip.innerHTML = '手机号不能为空';
            return false;
        }
        if (!reg.test(val)) {
            userPhoneTip.innerHTML = '手机号格式不正确';
            return false;
        }
        userPhoneTip.innerHTML = '';
        return true;
    };
    // 密码
    let checkPass = function checkPass() {
        let val = userPassInp.value.trim(),
            reg = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[\d(a-z)(A-Z)]{6,16}$/;
        if (val.length === 0) {
            userPassTip.innerHTML = '密码不能为空';
            return false;
        }
        if (!reg.test(val)) {
            userPassTip.innerHTML = '密码格式不正确';
            return false;
        }
        userPassTip.innerHTML = '';
        return true;
    };
    // 确认密码
    let checkPassC = function checkPassC() {
        let val = userPassConfirmInp.value.trim(),
            val2 = userPassInp.value.trim();
        if (val !== val2) {
            userPassConfirmTip.innerHTML = '密码不一致';
            return false;
        }
        userPassConfirmTip.innerHTML = '';
        return true;
    };
    // 提交
    let handel = function handel() {
        if (!checkName() || !checkEmail() || !checkPass() || !checkPassC() || !checkPhone()) {
            return;
        }
        alert('请去登录');
    }
    return {
        init() {
            userNameInp.onblur = checkName;
            userEmailInp.onblur = checkEmail;
            userPhoneInp.onblur = checkPhone;
            userPassInp.onblur = checkPass;
            userPassConfirmInp.onblur = checkPassC;
            submit.onclick = handel;
        }
    };
})();
reginModule.init();

2.5.3 Эффекты

3. Обычный захват

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

  • ОбычныйRegExp.prototypeметоды on (exec, test)
  • нитьString.prototypeМетоды, поддерживающие обработку регулярных выражений (заменить, сопоставить, разделить...)

3.1 EXEC (метод на регулярном прототипе)

на основеexecРеализовать обычный захват, который имеет два свойства: ленивый и жадный.
Поэтому есть поговорка: нельзя быть слишком «обычным» хахаха

3.1.1 Лень: поймать только один по умолчанию

  • Полученный результатnullили массив
    • Первый элемент: контент, снятый на этот раз
    • Другие предметы: соответствующие содержанию этого отдельного цикла малой группы.
    • index: начальный индекс текущего содержимого захвата в строке.
    • input: необработанная строка
  • каждое исполнениеexec, может быть захвачен только тот, который соответствует обычным правилам, но по умолчанию мы выполняем сто раз, и полученный результат всегда соответствует первому, а остальные не могут быть захвачены
let str = 'name2020name2020name2020';
    reg =/\d+/;
console.log(reg.exec(str));//["2020", index: 4, input: "name2020name2020name2020", groups: undefined]

3.1.2 Ленивое решение

  • reg.lastIndex: Начальная позиция индекса следующего совпадения текущего регулярного выражения
let str = 'name2020name2020name2020';
    reg =/\d+/;
console.log(reg.lastIndex);//0

"причина:"По умолчанию значение lastIndex не будет изменено, и каждый раз поиск будет начинаться с начала строки, поэтому всегда будет найден первый. Таким образом, пока значение lastIndex изменено, эта проблема может быть решена.
"Решение:"установить глобальный модификатор g

После установки глобального модификатора g первое совпадение завершается, и значение lastIndex будет изменено само собой.
Когда все захвачены, результат повторного захвата равен нулю, но lastIndex возвращается к начальному значению, равному нулю, и захват снова начинается с первого...
Основываясь на тесте соответствия проверки, LastIndex будет изменен

3.1.3. Инкапсулируйте метод для решения обычной лени

Требование: напишите метод execAll и выполните его один раз, чтобы зафиксировать все совпадающие результаты (предполагается, что должен быть установлен глобальный модификатор g)

~ function(){
  function execAll(str = ''){
    if(!this.global) return this.exec(str);
    let ary = [],
        res = this.exec(str);
    while(res){
        ary.push(res[0]);
        res = this.exec(str);        
    }      
    return  ary.length ===0?null:ary;
  }
  RegExp.prototype.execAll = execAll;
}();
let reg = /\d+/g,
    str = 'name2020name2020';
console.log(reg.execAll(str));

3.1.4 Жадный

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

let str = 'name2020',
    reg = /\d+/g;
 console.log(str.match(reg));   

3.1.5 Решение обычной жадной задачи

Устанавливается после метасимвола квантификатора

let str = 'name2020',
    reg = /\d+?/g;
 console.log(str.match(reg));   

3.2 Обычный захват группы () | метод сопоставления строк

Проанализируйте результаты следующих каштанов:

  • Пункт первый: результат большого регулярного матча
  • Остальное: каждая небольшая группа индивидуально сопоставляет захваченные результаты.
  • Если группировка установлена ​​(изменение приоритета), но при захвате не нужно захватывать отдельно, можно обрабатывать на основе ?: без захвата последнего элемента:/^([1-9]\d{5})((19|20)\d{2})(0[1-9]|10|11|12)(0[1-9]|[1-2]\d|30|31)\d{3}(?:\d|x)$/i
//身份证号
let str = '130222195202303210',
    reg =/^([1-9]\d{5})((19|20)\d{2})(0[1-9]|10|11|12)(0[1-9]|[1-2]\d|30|31)\d{3}(\d|x)$/i;
console.log(reg.exec(str));
console.log(str.match(reg));
//["130222195202303210", "130222", "1952", "19", "02", "30", "0", index: 0, input: "130222195202303210", groups: undefined]

================================================

  • в строкеmatchМетод может собирать все совпадающие данные за одно выполнение (при условии, что для регулярного также должно быть установлено значение g)
  • После добавления г,matchНе могу получить то, что в малой группе
let reg = /\d+/g;
console.log('name2020name2020'.match(reg));//["2020", "2020"]
//既要捕获到{0},也要捕获到0
let str = '{0}年{1}月';
    reg = /\{(\d)\}/g;
console.log(reg.exec(str));   
console.log(str.match(reg));

3.3 заменить (метод на строковом прототипе)

само по себе означает замену строки. Сочетание регулярного использования здесь имеет следующие характеристикиstr = str.replace(reg,func);

  • Во-первых, для сопоставления будут использоваться reg и func, и как только совпадение будет зафиксировано, функция func будет выполнена один раз.
  • И будет передавать результат каждого захвата (такой же, как результат, захваченный exec) в функцию func
  • То, что возвращается в функции func, эквивалентно замене результата большого регулярного совпадения в исходном символе на что?
//把-替换成/(不使用正则的时候需要多次执行这个方法,但是正则可以一次替换,前提是加g)
let str = '2020-04-09';
str = str.replace(/-/g,'/');
console.log(str);
let str = '{0}年{1}月';
let reg = /\{\d\}/g;
str = str.replace(reg,(...args)=>{
  console.log(args);//存储的是每次正则捕获的结果
  return 1;
})
console.log(str);//'1年1月'

4. Применение метода захвата в регулярных

4.1 Строка формата времени

  • Если месяц и день меньше десяти цифр, добавляются нули.
  • Изменить формат года месяц день
//方法一
let time = '2020-4-9';
let arr = time.match(/\d+/g);//拿到每一项
arr = arr.map(item=>item.length<2?'0'+item:item);
time = `${arr[0]}年${arr[1]}月${arr[2]}日`;
console.log(time);
//方法二
let time = '2020-4-9';
let arr = time.match(/\d+/g);//拿到每一项
arr = arr.map(item=>item.length<2?'0'+item:item);
let template = '{0}年{1}月{2}日';
template = template.replace(/\{(\d+)\}/g, (value, group) => {
  return arr[group]; //=>返回啥就是把TEMPLETE中大正则本次匹配的结果替换成啥
});
console.log(template); 
//方法三
let time = '2020-4-9';
String.prototype.formatTime = function formatTime(template) { 
 let arr = this.match(/\d+/g).map(item => {
   return item.length < 2 ? '0' + item : item;
 });
 template = template || '{0}年{1}月{2}日 {3}时{4}分{5}秒';
 return template.replace(/\{(\d+)\}/g, (_, group) => {
  return arr[group] || "00";
 });
}; 
console.log(time.formatTime());

4.2 Символ с наибольшим количеством вхождений в строку, сколько раз

//方法一
let str = "qwerttydsdsssfggg";
let ary = [...new Set(str.split(''))];
let max = 0;
let code = '';
for (let i = 0; i < ary.length; i++) {
 //创建正则匹配字符 
 let reg = new RegExp(ary[i], 'g');
 //利用match找出对应字符在中字符串中出现的地方,取匹配的返回数组的长度,即是对应字符串出现的次数
 let val = str.match(reg).length;
 //更新出现次数最高的字符与次数
 if (val > max) {
  max = val;
  code = ary[i];
 } else if (val === max) { //处理不同字符出现次数相同的情况
  code = `${code}、${ary[i]}`;
 }
}
console.log(`出现次数最多的字符是:${code},次数为:${max}`); 
//方法二
let str = "sfsdfsgdsdgdfg";
let obj = {};
// str.match(/[a-zA-Z]/g) <==> str.split('')
str.match(/[a-zA-Z]/g).forEach(item => {
 // 每一次存储之前,验证一下对象中是否已经包含这个字符,如果有,则代表之前存储过,我们此时让数量累加1即可
 if (obj[item] !== undefined) {
  obj[item]++;
  return;
 }
 obj[item] = 1;
});
let max = 0,
 result = '';
for (let key in obj) {
 let val = obj[key];
 if (val > max) {
  max = val;
  result = key;
 } else if (val === max) {
  result += `|${key}`;
 }
}
console.log(max, result); 
//方法三
let str = "sfsdfsdsfdgffd";
let arr = str.split('').sort((a, b) => {
 // 字符比较
 return a.localeCompare(b);
});
let max = 1,
 result = '',
 temp = 1;
for (let i = 0; i < arr.length - 1; i++) {
 let curr = arr[i],
  next = arr[i + 1];
 if (curr === next) {
  temp++;
  if (temp > max) {
   max = temp;
   result = curr;
  }
 } else {
  temp = 1;
 }
}
console.log(max, result); 
//方法四
let str = "sfsdsdgsdgsg";
str = str.split('').sort((a, b) => a.localeCompare(b)).join('');
// console.log(str);//=>"aeefghhhiilnnoopsuuuxzz"
let ary = str.match(/([a-zA-Z])\1+/g).sort((a, b) => b.length - a.length);
let max = ary[0].length,
 res = [ary[0].substr(0, 1)];
for (let i = 1; i < ary.length; i++) {
 let item = ary[i];
 if (item.length < max) {
  break;
 }
 res.push(item.substr(0, 1));
}
console.log(`出现次数最多的字符:${res},出现了${max}次`); 
//方法五
let str = "fdsgsgdfhi",
 max = 0,
 res = [],
 flag = false;
str = str.split('').sort((a, b) => a.localeCompare(b)).join('');
for (let i = str.length; i > 0; i--) { 
 let reg = new RegExp("([a-zA-Z])\\1{" + (i - 1) + "}", "g");
 str.replace(reg, (content, $1) => {
  res.push($1);
  max = i;
  flag = true;
 });
 if (flag) break;
}
console.log(`出现次数最多的字符:${res},出现了${max}次`);

4.3 Получить информацию о параметре в URL-адресе (может также содержать значение HASH)

String.prototype.queryURLParams = function queryURLParams() {
 let obj = {};
 // 哈希值值的处理
 this.replace(/#([^?=#&]+)/g, (_, group) => obj['HASH'] = group);
 // 问号传参信息的处理
 this.replace(/([^?#=&]+)=([^?#=&]+)/g, (_, group1, group2) => {
  obj[group1] = group2;
 });
 return obj;
};
let str = 'http://www.baidu.cn/?lx=1&from=weixin&name=xxx#video';
let obj = str.queryURLParams();
console.log(obj);

4,4 миллиметра: реализация Migratival

String.prototype.millimeter = function millimeter() {
 return this.replace(/\d{1,3}(?=(\d{3})+$)/g, value => {
  return value + ',';
 });
};
let str = "2312345638";
str = str.millimeter();
console.log(str); //=>"2,312,345,638"

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