Карта мозга из этой статьи скоро появится
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. Левая часть вопросительного знака — метасимвол квантификатора: отменить жадность при захвате;
-
- (?:): только совпадение без захвата;
- 4.(?=): предварительная проверка вперед;
-
- (?!) Отрицательный прогноз
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"
Написано здесь, можно сказать, что обучение регулярности почти освоено, (вы должны вспомнить, что это такое, это будет безумие, хахаха. Это очень выжигает мозги, но мы должны научиться этому с энергией сосания молоко. хахаха). Организовать это непросто, двигайте своими ручонками и оставьте сердечко для маленькой девочки.