Регулярные выражения, также известные как регулярные выражения. (Английский: регулярное выражение, часто сокращенно обозначаемое как регулярное выражение, регулярное выражение или RE в коде)
правила работы со строками
- может обрабатывать только строки
- Это правило: вы можете проверить, соответствует ли строка определенному правилу (тест), или вы можете зафиксировать содержимое строки, которая соответствует правилу (exec / match...)
let str = "good good study , day day up!";
//=>学正则就是用来制定规则(是否包含数字)
let reg = /\d+/;
reg.test(str); //=>false
str = "2020-04-07";
reg.exec(str); //=>["2020",index:0,inputs:"原始字符串"]
1. На регулярной основе (RegExp)
1. Определение
Определение: это правило обработки строк
- Regular в JS — это справочный тип данных
2. Обычный способ письма
Поскольку конструктор передает строку, \ необходимо написать дважды, чтобы представить косую черту.
- Буквальный способ: пусть reg = /\d+/g;
- Пример: let reg = new RegExp("\\d+","g");
- Когда некоторые символы регулярности должны быть переменными, выбирается этот метод.
Разница между двумя способами
- Когда частью регулярного выражения является значение, хранящееся в переменной
//1.两个斜杠中间包起来的都是元字符(如果正则中要包含某个变量的值,则不能使用字面量方式创建)
let type = "xiaozhima";
reg = /^@"+type+"@$/;
console.log(reg.test("@xiaozhima@")); //=>false
console.log(reg.test('@"""typeeeee"@')); //=>true
//2.这种情况只能使用构造函数方式(因为它传递的规则是字符串,只有这样才能进行字符串拼接)
reg = new RegExp("^@"+type+"@$");
console.log(reg.test("@xiaozhima@"));//=>true
3. Регулярное использование
Методы на обычном RegExp.prototype
- матч тест
- Capture Exec.
- матч тест
- Напишите регулярку (установите набор правил): чтобы проверить, соответствует ли определенная строка этому правилу;
- захватить исполнителя
- Напишите обычный (установите набор правил): чтобы получить символы в строке, которые соответствуют этому правилу, для
Методы в String.prototype, поддерживающие обработку регулярных выражений
- replace
- match
- splite
- .......
4. Обычная композиция (просто перечислите некоторые часто используемые)
Регулярные выражения составлены из ряда модификаторов и некоторых метасимволов (метасимволов).
- Метасимволы состоят из обычных символов и некоторых специальных символов:
- Общие символы включают прописные и строчные буквы и цифры,
- Специальные метасимволы имеют особое значение, которое мы объясним ниже.
-1).Модификатор
Используется вне регулярного выражения:
- Например:
/abc/iвнутреннийi
| персонаж | имея в виду | английское полное имя |
|---|---|---|
| i | игнорировать регистр | ignoreCase |
| m | многострочное совпадение | multiline |
| g | глобальное совпадение | global |
| s | Сделайте так, чтобы «точка» соответствовала любому символу, включая \n и \r | |
| ...... | ...... |
-2).Мета символы
Содержимое между косыми чертами называется метасимволом.
- Например:
/abc/iвнутреннийabc
обычные метасимволы
Это обычные прописные и строчные буквы и цифры;
специальные метасимволы
Метасимволы со специальным значением
| персонаж | имея в виду |
|---|---|
| \ | Экранирование символов (преобразование символов со специальным значением в сами символы или экранирование обычных символов в символы со специальным значением) |
| \d | Число от 0 до 9 |
| \D | Любой символ, кроме 0-9 |
| \w | Цифры, буквы, символы подчеркивания (строчные w) |
| \W | Любой символ, кроме цифр, букв и знаков подчеркивания (заглавная W) |
| ^ | с какого персонажа начать |
| $ | какой персонаж заканчивается |
| . | Представляет все символы, кроме новой строки |
| \n | представляет новую строку |
| \s | Пробельный символ (включая пробелы, табуляции, новые строки и т. д.) |
| \t | один символ табуляции (одна клавиша TAB: 4 пробела) |
| \b | соответствовать границе слова |
| ---- | ---- |
| x|y | означает или; x или y |
| [xyz] | Представляет или; x или y или z (отличие от предыдущего: [] может писать только один символ до и после, а | может быть группой чисел до и после) |
| [^xy] | Любой символ, кроме xy |
| [a-z] | Любой символ от a~z Строчные буквы английского алфавита |
| [^a-z] | Любой символ, кроме a-z |
| ( ) | Группировка и усиление приоритетов |
| (?:) | только совпадение без захвата |
| знак равно | Положительный позитивный прогноз |
| (?!) | положительный отрицательный взгляд вперед |
| ...... | ...... |
метасимвол квантификатора
Они используются позже в других метагаторах
- Например: /abc{3}/ => {3}
| персонаж | имея в виду |
|---|---|
| ? | Предыдущий символ появляется 0 или 1 раз |
| + | Предыдущий символ появляется один или несколько раз |
| * | Предыдущий символ появляется 0 или более раз |
| {n} | Предыдущий символ появляется n раз подряд |
| {n,m} | Предыдущий символ появляется от n до m раз подряд |
| {n,} | Предыдущий символ появляется от n до нескольких раз подряд |
| ...... | ...... |
Интеллект-карты: регулярные основы
2. Регулярное сопоставление (тест)
Напишите регулярку (установите набор правил): чтобы проверить, соответствует ли определенная строка этому правилу;
1. Грамматика
- Обычный.тест(строка)
2. Возвращаемое значение
- Соответствует обычным правилам: возвращает TRUE
- Не соответствует обычным правилам: вернуть FALSE
3. Несколько примеров 🌰 Практика
Упражнения, связанные с \d,?,{n,m}
var str = '小芝麻666';
var reg = /\d/; // 只要字符串中含有数字 即可
console.log(reg.test(str)) // true
console.log(reg.test('werwf2ergdfg'))//true
console.log(reg.test('aefasdfsdfsf'))//false
console.log(reg.test('3453245254')) // true
var reg = /\d?/; // 数字出现0或1次 字符串有没有数字都满足情况
console.log(reg.test('xiaozhima666')) // true
console.log(reg.test('werwf2ergdfg'))//true
console.log(reg.test('aefasdfsdfsf'))//true
console.log(reg.test('3453245254')) // true
var reg = /\d{2,4}/; // 字符串中有没有连续2个或者3个数字 或者4个数字
// /\d\d/ /\d\d\d/ /\d\d\d\d/
console.log(reg.test('xiaozhima666')) // true
console.log(reg.test('werwf2ergdfg'))//false
console.log(reg.test('aefasdfsdfsf'))// false
console.log(reg.test('3453245254')) // true
var reg = /\d{2}/; // 字符串中 有两个连续的数字 即可
console.log(reg.test('xiaozhima666')) // true
console.log(reg.test('werwf2e3rgdfg'))// false
console.log(reg.test('aefasdfsdfsf'))// false
console.log(reg.test('3453245254')) // true
Упражнения, связанные с открытием ^ и закрытием $
- В регулярном выражении есть ^ $: вся строка должна удовлетворять регулярному выражению
- В регулярном выражении нет ^ $: до тех пор, пока в строке есть символы, соответствующие этому регулярному выражению
var reg = /^\d/; // 要求字符串是 以数字开头的
console.log(reg.test('xiaozhima666')) // false
console.log(reg.test('werwf2e3rgdfg'))// false
console.log(reg.test('aefasdfsdfsf'))// false
console.log(reg.test('3453245254')) // true
var reg = /^\d{2,3}/; // 要求 字符串 是以 两个或者三个数字开头的 即可
console.log(reg.test('1xiaozhima666')) // false
console.log(reg.test('22werwf2e3rgdfg'))// true
console.log(reg.test('432aefasdfsdfsf'))// true
console.log(reg.test('3453245254')) // true
var reg = /d{2,3}/; //字符串中 需要有连续两到三个d
console.log(reg.test('1xiaozhima666')) // false
console.log(reg.test('22werwf2e3rgdfg'))// false
console.log(reg.test('432aefasdfsdfsf'))// false
console.log(reg.test('3453245254')) // false
var reg = /\d$/; // 字符串需要是一个 数字 结尾的字符
console.log(reg.test('1xiaozhima666')) // true
console.log(reg.test('22werwf2e3rgdfg'))// false
console.log(reg.test('432aefasdfsdfsf'))// false
console.log(reg.test('3453245254')) // true
var reg = /\d{4,6}$/; // 以4-6个数字结尾的字符串
console.log(reg.test('1xiaozhima666')) // false
console.log(reg.test('22werwf2e3rgdfg'))// false
console.log(reg.test('432aefasdfsdfsf3456'))// true
console.log(reg.test('3453245254')) // true
// 正则中有 ^ $ 他就是说字符串必须全部满足正则
// 正则中没有 ^ $ 只要字符串中有符合这个正则的字符即可
// var reg2 = /\d/;
var reg = /^\d$/; // 以数字开头 以数字结尾:以一个数字开头 还得以这个数字结尾
console.log(reg.test('432aefasdfsdfsf3456'))// false
console.log(reg.test('3453245254')) // false
console.log(reg.test('3333')) // false
console.log(reg.test('1')) // true
console.log(reg.test('9'))// true
console.log(reg.test('4'))// true
console.log(reg.test('5'))// true
console.log(reg.test('8'))// true
var reg = /^\d{2,3}$/;// 以两到三个数字开头 还得以这两到三个数字结尾
// 也就是说 这个正则只能匹配 两到三位数字的字符串
console.log(reg.test('432aefasdfsdfsf3456'))// false
console.log(reg.test('3453245254')) // false
console.log(reg.test('3333')) // false
console.log(reg.test('1')) // false
console.log(reg.test('9'))// false
console.log(reg.test('4'))// false
console.log(reg.test('5'))// false
console.log(reg.test('8'))// false
console.log(reg.test('18'))// true
var reg = /^\d+.\d{2}$/;
console.log(reg.test('123.345'))// false
console.log(reg.test('123r34')) // true
console.log(reg.test('1235345'))//true
console.log(reg.test('123r345')) // false
console.log(reg.test('123 345')) // false
console.log(reg.test('123r45')) // true
var reg = /\\d+/;// 要去匹配一个 \ 后边是1到多个d字符 ‘\dd......’
console.log(reg.test('qqwewer'))// false
console.log(reg.test('134543'))// false
console.log(reg.test('134543d'))// false
console.log(reg.test('dd'))// false
console.log(reg.test('\dd'))// true
console.log(reg.test('\\dd')) //true
Скобки [ ]: или похожие упражнения
- Символы в скобках обычно представляют свое собственное значение.
- В []: метасимвол квантификатора |.. больше не имеет специального значения;
- \d все еще 0-9 в квадратных скобках
- Символ «-» в [] соответствует соответствующему значению кода спрашивающего;
- Если вы хотите, чтобы '-' представлял себя в []: рекомендуется поставить его в конце
- Например: /[\w@#?-]+/
- В квадратных скобках нет кратных цифр
var reg = /[a-c]/;// 就是 有abc中的任意一个字符 即可
console.log(reg.test('aeadfgergdfgd'))//true
console.log(reg.test('234werrfrb')) // true
console.log(reg.test('acaca')) // true
console.log(reg.test('bbbbb')) // true
// [] 中的字符 ‘-’ 是按照 对应的的阿斯克码值对应的
// var reg = /[c-a]/ ;是不可以的会报错
// var reg = /[C-a]/ ;// ASCII:67(大C)-97(小a)
var reg = /[c\-a]/ ;// c 或者 ‘-’ 或者 a ;这里的‘-’没有意义了,只是一个‘-’
var reg = /[.]/;// 在 [] 中的点 就代表 点儿本身
//=>[] 中的:量词元字符 | . 不再具有特殊含义了;
var reg = /^[1.2]$/;// 该正则 只能匹配一个字符; 1或.或2
console.log(reg.test('1.2'))//false;
console.log(reg.test('1q2'))//false
console.log(reg.test('1')) // true
console.log(reg.test('2'))// true
упражнения, связанные с точками
var reg = /^1.2$/;// 该正则 1开头 2结尾 中间有一个任意字符
console.log(reg.test('1.2'))//;true
console.log(reg.test('1q2'))//true
console.log(reg.test('1')) // false
console.log(reg.test('2'))// false
Выход из связанных упражнений
- Escape в обычном: экранирование символов со специальным значением в обычном
- Экранирование в строке: это экранирование символа со специальным значением в строке в сам символ;
var reg = /^1\.2$/;// 该正则 1开头 2结尾 中间有一个点
console.log(reg.test('1.2'))//;true
console.log(reg.test('1q2'))//false
console.log(reg.test('1')) // false
console.log(reg.test('2'))// false */
// 转义 一个是正则中的转义 一个是字符串中的转义
//正则中的转义 就是把 正则中 有特殊含义的字符 转义字符本身
//字符串中的转义 就是把 字符串中 有特殊含义的字符 转义成字符本身;' " \
Вертикаль |: или похожие упражнения
- Прямые x|y будут иметь очень грязную проблему с приоритетом.Как правило, когда мы пишем, мы группируемся скобками, потому что скобки меняют приоритет обработки => скобки: группировка
var reg = /18|19/;// 含有 18或者19即可
console.log(reg.test('18'))
console.log(reg.test('19'))
console.log(reg.test('189'))
console.log(reg.test('1819'))
console.log(reg.test('819'))
console.log(reg.test('1918'))
console.log(reg.test('118'))
var reg = /^18|19/;// 18开头的 或者 含有19的 就是true;
console.log(reg.test('18')) // true
console.log(reg.test('19')) // true
console.log(reg.test('189'))//true
console.log(reg.test('1819'))//true
console.log(reg.test('819'))//true
console.log(reg.test('1918'))//true
console.log(reg.test('118')) // false
console.log(reg.test('119')) // true
var reg = /^18|19$/;// 18开头的 或者 以19结尾的 就是true;
console.log(reg.test('18')) // true
console.log(reg.test('19')) // true
console.log(reg.test('189'))//true
console.log(reg.test('1819'))//true
console.log(reg.test('819'))//true
console.log(reg.test('1918'))//false
console.log(reg.test('118')) // false
console.log(reg.test('119')) // true
// 编写一个正则 只有18 或者 19 匹配的结果是 true; 其他都是false;
var reg = /^(18|19)$/;// 只能匹配18或者19
console.log(reg.test('18')) // true
console.log(reg.test('19')) // true
console.log(reg.test('189'))//false
console.log(reg.test('1819'))//false
console.log(reg.test('819'))//false
console.log(reg.test('1918'))//false
console.log(reg.test('118')) // false
console.log(reg.test('119')) // false
var reg = /^[18|19]$/;// 只能匹配 1 8 | 1 9 五个中的一位
var reg = /^1[89]$/; // 以1开头 后边是 8或者9 结尾;
var reg = /^[18]9$/; // 以1或者8开头 9结尾
var reg = /^1(8|9)$/;// 以1开头 后边是 8或者9 结尾;
4. Упражнения по применению
-1), напишите регулярку, которая может сопоставить, является ли номер мобильного телефона, введенный пользователем, легальным (широким)
правило:
- 1. Начните с 1
- 2. 11 цифр
- 3. Вторая цифра не может быть 012
let rex = /^1[3-9]\d{9}$/
-2), напишите обычный, который может соответствовать допустимым числам
правило:
- 1. Знак + - может появиться или не появиться: [+-]?
- 2. Можно использовать одну цифру 0-9, и первая позиция нескольких цифр не может быть 0: (\d|([1-9]\d+))
- 3. Десятичной части может не быть, а если есть, то должна быть десятичная точка + число: (.\d+)?
let reg = /^[+-]?(\d|([1-9]\d+))(\.\d+)?$/;
-3), напишите регулярку, которая сможет проверить настоящее имя
правило:
- 1. Китайские иероглифы: /^[\u4E00-\u9FA5]$/
- 2. Длина имени 2~10 цифр
- 3. Могут быть переведены имена китайскими иероглифами: (·[\u4E00-\u9FA5]{2,10}){0,2}
let reg = /^[\u4E00-\u9FA5]{2,10}(·[\u4E00-\u9FA5]{2,10}){0,2}$/;
-4), напишите регуляр может соответствовать возрасту от 18 до 65 лет
правило:
- 1. Целое число
- 18-19 ;20-59 : [2-5]\d ; 6[0-5]
let reg = /^(1[89]|[2-5]\d|6[0-5])$/;
-5), пишите обычный может совпадать с почтовым ящиком
Правило 1: Имя почтового ящика состоит из «цифр, букв, знаков подчеркивания, -, .», но -/. не может стоять подряд или в начале
1. Начните с цифры и буквы подчеркивания (1 или более цифр).
2. Это также может быть подчеркивание цифр и букв или подчеркивание цифр и букв, от целого нуля до нескольких раз.
=> \w+((-\w+)|(.\w+))*
Правило второе:
1. @, за которым следуют: цифры, буквы (1-несколько цифр)
=> @[A-Za-z0-9]+
2. Дополнение к имени после @
- Мультидоменное имя .com.cn
- Деловая электронная почта xxx@xxxxxxxx-xxx-office.com
=> ((.|-)[A-Za-z0-9]+)*
3. Сопоставьте последнее доменное имя (.com/.cn/.org/.edu/.net...)
=> .[A-Za-z0-9]+
let reg = /^\w+((-\w+)|(\.\w+))*@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/;
-6), пишите обычный может совпадать с ID номером
правило:
- 1. Всего 18 цифр
- 2. Последняя цифра может быть X
- 3, первые шесть ID: провинциальные города и округа (первый бит не 0)
- 4, год 19 или 20: (19 | 20) \ Д {2})
- 5. Месяц 01-12: (0[1-9]|1[0-2])
- 6. Дата 01-31: (0[1-9]|[1-2]\d|3[01])
- 7. Последняя цифра => X или число: (\d|X)
- 8. Предпоследняя цифра => четный женский нечетный мужской: (\d{2}(\d))
let reg = /^[1-9]\d{5}((19|20)\d{2})(0[1-9]|1[0-2])(0[1-9]|[1-2]\d|3[01])\d{3}(\d|X)$/i;
-7) написать регулярку, которая может сопоставлять, соответствует ли введенный пользователем пароль правилам;
правило:
- 1. 8-18 бит
- 2. И прописные, и строчные буквы должны иметь цифры.
function judge(str) {
if (str.length < 8 || str.length > 18) return false
if (!/[A-Z]/.test(str)) return false
if (!/[a-z]/.test(str)) return false
if (!/\d/.test(str)) return false
return true;
}
let reg = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[a-zA-Z0-9]{8,18}$/
//=> 必须有特殊字符时
let reg = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[#?&*-])[a-zA-Z0-9#?&*-]{8,18}$/
//=> 密码是由8-18位的数字或者字母组成 不要求所有类型都存在
let reg = /^[0-9A-Za-z]{8,18}$/;
Также поделитесь обычным инструментом поиска:Инструменты для новичков
Три, обычный захват (exec)
Напишите обычный (установите набор правил): чтобы получить символы в строке, которые соответствуют этому правилу, для
1. Грамматика
- Обычный .exec (строка)
2. Помещение
Предпосылкой для реализации регулярного захвата является то, что текущий обычный код должен соответствовать строке, если он не совпадает, захваченный результат равен нулю.
let str = "xiaozhima2019xiaozhima2020xiaozhima2021";
let reg = /^\d+$/;
console.log(reg.test(str)); //=>false
console.log(reg.exec(str)); //=>null
3. Возвращаемое значение
- Если соответствующий текст найден, возвращается массив
- Первый элемент массива: содержимое, захваченное на этот раз.
- Другие элементы: на этот раз соответствующие контенту, захваченному небольшой группой отдельно.
- index: начальный индекс текущего содержимого захвата в строке
- ввод: необработанная строка
- ......
- если не найдено, иначе вернуть
null
let str = "xiaozhima2019xiaozhima2020xiaozhima2021";
let reg = /\d+/;
console.log(reg.exec(str));
4. Особенности захвата
-1), ленивый
каждое исполнение
exec, может быть захвачен только тот, который соответствует обычным правилам.По умолчанию мы выполняем сто раз, и полученный результат всегда соответствует первому, а остальные не могут быть захвачены.
let str = "xiaozhima2019xiaozhima2020xiaozhima2021";
let reg = /\d+/;
console.log(reg.exec(str));
console.log(reg.exec(str));
console.log(reg.exec(str));
console.log(reg.exec(str));
console.log(reg.exec(str));
ленивое решение
Чтобы решить лень, мы должны сначала узнать, почему у обычного есть эта функция?
- Тогда давайте взглянем на содержимое консольного вывода написанного нами обычного.
let str = "xiaozhima2019xiaozhima2020xiaozhima2021";
let reg = /\d+/;
console.dir(reg);
let str = "xiaozhima2019xiaozhima2020xiaozhima2021";
let reg = /\d+/;
console.log(reg.lastIndex); //=>0 下面匹配捕获是从STR索引零的位置开始找
console.log(reg.exec(str));
console.log(reg.lastIndex); //=>0 第一次匹配捕获完成,lastIndex没有改变,所以下一次exec依然是从字符串最开始找,找到的永远是第一个匹配到的
reg.lastIndex: Начальная индексная позиция текущего регулярного следующего совпадения (тогда мы можем узнать причину регулярной лени)
- Причина ленивого захвата: по умолчанию
lastIndexЗначение не будет изменено, каждый раз он ищется с начала строки, поэтому всегда находится только первое значение.
Теперь, когда мы знаем, почему регуляр такой "ленивый", мы можем "прописать правильное лекарство", чтобы вылечить его лень😄
Обходной путь: глобальные модификаторы
g
let str = "xiaozhima2019xiaozhima2020xiaozhima2021";
let reg = /\d+/g;
console.log(reg.exec(str)); //=>["2019"...]
console.log(reg.lastIndex); //=> 13 //=>设置全局匹配修饰符g后,第一次匹配完,lastIndex会自己修改
console.log(reg.exec(str)); //=>["2020"...]
console.log(reg.lastIndex); //=> 26
console.log(reg.exec(str)); //=>["2021"...]
console.log(reg.lastIndex); //=> 39
console.log(reg.exec(str)); //=>null 当全部捕获后,再次捕获的结果是null,但是lastIndex又回归了初始值零,再次捕获又从第一个开始了...
console.log(reg.lastIndex); //=>0
console.log(reg.exec(str)); //=>["2019"...]
- Затем давайте проверим: повлияет ли обычное сопоставление и сопоставление строк?
lastIndex
let str = "xiaozhima2019xiaozhima2020xiaozhima2021";
let reg = /\d+/g;
if (reg.test(str)) {
//=>验证一下:只有正则和字符串匹配我们在捕获
console.log(reg.lastIndex); //=>11 基于TEST匹配验证后,LASTINDEX已经被修改为第一次匹配后的结果,所以下一次捕获不再从头开始了
console.log(reg.exec(str)); //=>["2020"...]
}
Упражнение с требованием: напишите метод execAll и выполните его один раз, чтобы получить все совпадающие результаты (предполагается, что должен быть установлен глобальный модификатор g)
~ function () {
function execAll(str = "") {
//=>str:要匹配的字符串
//=>this:RegExp的实例(当前操作的正则)
//=>进来后的第一件事,是验证当前正则是否设置了G,不设置则不能在进行循环捕获了,否则会导致死循环
if (!this.global) return this.exec(str);
//=>ARY存储最后所有捕获的信息 RES存储每一次捕获的内容(数组)
let ary = [],
res = this.exec(str);
while (res) {
//=>把每一次捕获的内容RES[0]存放到数组中
ary.push(res[0]);
//=>只要捕获的内容不为NULL,则继续捕获下去
res = this.exec(str);
}
return ary.length === 0 ? null : ary;
}
RegExp.prototype.execAll = execAll;
}();
let reg = /\d+/g;
console.log(reg.execAll("金色2019@2020小芝麻")); //=> ["2019", "2020"]
//=>字符串中的MATCH方法,可以在执行一次的情况下,捕获到所有匹配的数据(前提:正则也得设置G才可以)
console.log("金色2019@2020小芝麻".match(reg));//=> ["2019", "2020"]
-2), жадность
По умолчанию при выполнении обычного захвата он получается по самому длинному результату, совпадающему с текущим регулярным захватом.
let str = "金色2019@2020小芝麻";
//=>正则捕获的贪婪性:默认情况下,正则捕获的时候,是按照当前正则所匹配的最长结果来获取的
let reg = /\d+/g;
console.log(reg.exec(str)); //=>["2019",......]
жадное решение
устанавливается после метасимвола квантификатора
?: Отменить жадность захвата (по кратчайшему результату обычного сопоставления)
let str = "金色2019@2020小芝麻";
reg = /\d+?/g;
console.log(reg.exec(str)); //=>["2",......]
Интеллект-карты: регулярное сопоставление и захват
В-четвертых, другие общеизвестные моменты регулярного
1. Вопросительный знак? Пять функций регуляризации:
Пять функций вопросительных знаков в регулярных выражениях:
- Оставленный знак вопроса - не-квантов мета Хамарактерирует: Метахарэльпволы квантификатора от имени себя, кажутся нулю один раз
- Слева от вопросительного знака находится метасимвол квантификатора: жадный при отмене захвата.
- (?:) только совпадения без захвата
- (?=) Упреждающий просмотр (должен что-то содержать)
- (?!) Отрицательный просмотр вперед (ничего не должно быть)
2. Три функции группировки ()
-1), первая роль малой группы: повысить приоритет
Требование: зафиксировать дату рождения и пол в идентификационном номере.
//=>第一项:大正则匹配的结果
//=>其余项:每一个小分组单独匹配捕获的结果
//=>如果设置了分组(改变优先级),但是捕获的时候不需要单独捕获,可以基于?:来处理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<input type="text"/>
<button>提交</button>
<h5></h5>
</body>
</html>
<script>
/*
点击提交按钮 h5标签展示 这个出生日期和性别
*/
let inp = document.querySelector('input'),
btn = document.querySelector('button'),
h5 = document.querySelector('h5');
btn.onclick = function(){
let val = inp.value;
var reg = /^[1-9]\d{5}((19|20)\d{2})(0[1-9]|1[0-2])(0[1-9]|[1-2]\d|3[01])\d{2}(\d)(\d|X)$/i;
let ary = reg.exec(val);
console.log(ary);
if(ary){
// 输入的是一个合法正则
let str = `这个人的出生日期是${ary[1]}年${ary[3]}月${ary[4]}日;性别是${ary[5]%2 ? '男' : '女'}`;
h5.innerHTML = str;
}else{
alert('不是一个合法的身份证号码')
}
}
</script>
-2), вторая роль малых групп: групповой захват
Требование: не только хотите захватить {число}, но также хотите получить номер отдельно, например: если вы найдете {0} в первый раз, вам также нужно получить 0 отдельно
//=>既要捕获到{数字},也想单独的把数字也获取到,例如:第一次找到 {0} 还需要单独获取0
let str = "{0}年{1}月{2}日";
//=>不设置g只匹配一次,exec和match获取的结果一致(既有大正则匹配的信息,也有小分组匹配的信息)
let reg = /\{(\d+)\}/;
console.log(reg.exec(str));
console.log(str.match(reg));
//["{0}", "0",...]
let reg = /\{(\d+)\}/g;
console.log(str.match(reg)); //=>["{0}", "{1}", "{2}"]
//多次匹配的情况下,match只能把大正则匹配的内容获取到,小分组匹配的信息无法获取
//=> 自己写一个方法,完成需求
let aryBig=[],
arySmall=[],
res=reg.exec(str);
while(res){
let [big,small]=res;
aryBig.push(big);
arySmall.push(small);
res=reg.exec(str);
}
console.log(aryBig,arySmall); //=>["{0}", "{1}", "{2}"] ["0", "1", "2"]
-3), третья роль малых групп: групповые ссылки
Ссылка на группу должна использовать «\number», чтобы она представляла то же самое содержимое, что и соответствующая группа.
//=>分组的第三个作用:“分组引用”
let str = "book"; //=>"good"、"look"、"moon"、"foot"...
let reg = /^[a-zA-Z]([a-zA-Z])\1[a-zA-Z]$/; //=>分组引用就是通过“\数字”让其代表和对应分组出现一模一样的内容
console.log(reg.test("book")); //=>true
console.log(reg.test("deep")); //=>true
console.log(reg.test("some")); //=>false
3. Другие способы и случаи регулярного захвата
-1), тест также может захватывать (предназначен для совпадения)
- RegExp.$&: получить содержимое текущего большого регулярного
- RegExp.$1~RegExp.$9: получить информацию о группах с первой по девятую после текущего регулярного совпадения.
let str = "{0}年{1}月{2}日";
let reg = /\{(\d+)\}/g;
console.log(reg.test(str)); //=>true
console.log(RegExp.$1); //=>"0" 获取当前本次匹配项中,第一个分组匹配的内容
console.log(reg.test(str)); //=>true
console.log(RegExp.$1); //=>"1" 获取当前本次匹配项中,第一个分组匹配的内容
console.log(reg.test(str)); //=>true
console.log(RegExp.$1); //=>"2" 获取当前本次匹配项中,第一个分组匹配的内容
console.log(reg.test(str)); //=>false
console.log(RegExp.$1); //=>"2" 存储的是上次捕获的结果
//=>RegExp.$1~RegExp.$9:获取当前本次正则匹配后,第一个到第九个分组的信息
-2), именование групп (новое в ES6)
Эквивалентно названию группы
- Синтаксис: ?
- После того, как сопоставление будет завершено позже, вы можете получить информацию, захваченную указанной группировкой имен, на основе групп в результате сопоставления.
reg = /^(?<A>\d{6})(?<B>\d{4})(?<C>\d{2})(?<D>\d{2})\d{2}(?<E>\d)(?:\d|X)$/;
let res = reg.exec(str);
console.log(res.groups.A);
console.log(res.groups.E);
Мы не будем здесь объяснять, мы рекомендуем учителя Руань Ифэна.Начало работы с ECMAScript 6В ней подробные пояснения, а сезам здесь не топором играть 😄
-3), один из методов захвата в строках и обычных словосочетаниях — совпадение
Мы кратко упомянули об этом выше, здесь мы в основном говорим о
matchа такжеesecразница
matchа такжеesecразница
- 1, установите глобальный модификатор
gна случай, если:-
execЗа одно выполнение может быть получен только один совпадающий результат.- Текущий результат содержит результаты сопоставления больших регулярных и малых групп.
- Если вы хотите захватить все, вам нужно выполнить несколько раз
-
matchВыполните один раз, чтобы получить всю обычную совпадающую информацию- Только большие регулярные совпадения и не содержат информации о сопоставлении малых групп.
-
- 2. Если не установлено
gна случай, если:- Можно зафиксировать только первый результат совпадения, и полученные результаты точно такие же (включая большую регулярную, малую группу)
-4), один из методов захвата в строках и обычных словосочетаниях - заменить
сам по себе смысл замены строки
- В случае неиспользования штатного, каждое выполнение
replaceЗаменить можно только одно, а многие требования невозможно решить без использования регулярных выражений
let str = "xiaozhima@2019|xiaozhima@2020";
//=>把"xiaozhima"替换成"小芝麻"
//1.不用正则,执行一次只能替换一个
str = str.replace("xiaozhima","小芝麻").replace("xiaozhima","小芝麻");
console.log(str);
//2.使用正则会简单一点
str = str.replace(/xiaozhima/g,"小芝麻");
console.log(str);
- Замените «jinse» на «jinsexiaozhima».
let str = "jinse@2019|jinse@2020";
//=>把"jinse"替换为"jinsexiaozhima"
str=str.replace("jinse","jinsexiaozhima").replace("jinse","jinsexiaozhima");
//"jinsexiaozhimaxiaozhima@2019|jinse@2020" 每一次替换都是从字符串第一个位置开始找的(类似于正则捕获的懒惰性)
let str = "jinse@2019|jinse@2020";
//=>基于正则g可以实现
str = str.replace(/jinse/g,"jinsexiaozhima");
Объедините обычные:
- Синтаксис: str = str.replace(рег,функция)
- Функции:
- 1. Сначала для сопоставления и захвата будут использоваться обычные и строковые значения. После захвата совпадения функция будет выполнена один раз.
- 2, и будет передавать результат каждого захвата (такой же, как результат, захваченный esec) в функцию
- Таким образом, вы можете использовать оператор остатка для получения результата каждого обычного совпадения.
- Порядок результатов: [Тайшо сопоставление, сопоставление небольших пакетов, начальный индекс захваченной исходной строки ......]
- 3. То, что возвращается в функции, эквивалентно замене результата большого регулярного совпадения в исходной строке на то, что
Случай: обработка строк времени
//=> 要求传入实参格式任意:xx-xx xx:xx ;但索引对应为: 0年 1月 2日 3时 4分 5秒
String.prototype.formatTime = function formatTime(template) {
// 1.根据操作的时间字符串获取年月日小时分钟秒等信息
let arr = this.match(/\d+/g).map(item => {
return item.length < 2 ? '0' + item : item;
});
// 2.解析格式化的模板,找到对应的时间,替换模板中的内容
template = template || '{0}年{1}月{2}日 {3}时{4}分{5}秒';
return template.replace(/\{(\d+)\}/g, (_, group) => {
return arr[group] || "00";
});
};
let time = "2020-4-8 16:36:8";
time = time.formatTime('{0}年{1}月{2}日');
console.log(time); //=> 2020年04月08日
Регистр: Сделать заглавной первую букву слова
let str = "good good study,day day up!";
let reg = /\b([a-zA-Z])[a-zA-Z]*\b/g;
//=>函数被执行了六次,每一次都把正则匹配信息传递给函数
//=>每一次ARG:["good","g"] ["good","g"] ["study","s"]...
str = str.replace(reg,(...arg)=>{
let [content,$1]=arg;
$1=$1.toUpperCase();
content=content.substring(1);
return $1+content;
});
console.log(str); //=>"Good Good Study,Day Day Up!"
Случай: обработка параметров URL
// 获取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.xxxxxxxxx.cn/?lx=1&from=weixin&name=xxx#video';
let obj = str.queryURLParams();
console.log(obj); //=> {HASH: "video", lx: "1", from: "weixin", name: "xxx"}
Кейс: Реализация обработки разделителя тысяч
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"