Регулярное введение в мастерство JavaScript

JavaScript

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

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

Основание

Регулярные выражения (регулярные выражения, часто сокращенно обозначаемые как regex, regexp или RE в коде) используют одну строку для описания и сопоставления серии шаблонов поиска строк, которые соответствуют синтаксическому правилу.

Режим поиска можно использовать для поиска текста и замены текста.

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

Создание регулярных выражений

Способ 1:

// 语法格式为: /正则表达式主体/修饰符(可选)
// 案例
var patt = /var/i
// var 是正则表达式主体
// i 是修饰符

Способ 2:

// 创建 RegExp 对象
// new RegExp(正则表达式主体[, 修饰符])
// RegExp(正则表达式主体[, 修饰符])
var patt = new RegExp('var', 'i')

Уведомление:/var/iсоздать ключевой объект регулярного выражения иnew RegExp(var, i)Создаваемые объекты не равны. Хотя они соответствуют одним и тем же правилам.

Модификаторы, определяющие совпадающие шаблоны:

модификатор описывать
i Выполните сопоставление без учета регистра.
g Сделать глобальное совпадение (найти все совпадения вместо того, чтобы останавливаться после того, как будет найдено первое совпадение).
m Выполните многострочное сопоставление.
s разрешать.чтобы соответствовать нескольким строкам
u Unicode, рассматривайте шаблон как последовательность точек последовательности Unicode Unicode;
y липкое совпадение; соответствует только вхождениям этого регулярного выражения в целевую строкуlastIndexИндекс, указанный свойством (и не пытается найти совпадение с каким-либо последующим индексом).

Классы персонажей

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

код иллюстрировать
. Соответствует любому символу, кроме новой строки. Уведомление:/[.]/соответствует точке символа.
\w Совпадение с буквами или цифрами, символами подчеркивания или китайскими иероглифами[A-Za-z0-9_]
\s соответствует любому пробелу[\f\n\r\t\v​\u00a0]
\d совпадение чисел[0-9]
\ для побега

Границы

код иллюстрировать
\b Соответствует началу или концу слова, например:/\bno/соответствовать"at noon"середина"no"
^ соответствует началу строки
$ Соответствует концу строки

Группировка и обратные ссылки

персонаж имея в виду
(x) Захватите скобки. Сопоставьте x и зафиксируйте совпадение./(foo)/сопоставить и захватить"foo bar."середина"foo". Совпадающая подстрока может быть元素[n]находится в объекте RegExp или является его свойством$nнайти в. Будет стоить производительность, если вам нужен захваченный массив, вы можете использовать скобки без захвата
\n Обратная ссылка на подстроку, совпавшую в n-й скобке (считая слева) в регулярном выражении./apple(,)\sorange\1/соответствовать"apple, orange, cherry, peach."середина"apple,orange,"(Прошлой,Нет)
(?:x) Незахватывающие скобки. Сопоставление x не фиксирует совпадение. Совпадения не могут быть снова доступны из результата. (рекомендовать)

повторить

код/синтаксис иллюстрировать
* Повторить ноль или более раз
+ повторить один или несколько раз
? повторить ноль или один раз
x*?
x+?
Наименее возможное совпадение, нежадный шаблон./".*?"/соответствовать"foo" "bar"середина"foo"
{n} повторить n раз
{n,m} Повторить от n до m раз

Утверждения

код/синтаксис иллюстрировать
x(?=y) Совпадение x только в том случае, если за x сразу следует y./Jack(?=Sprat)/только в'Jack'с последующим'Sprat'совпадение, когда
x(?!y) Совпадение x только в том случае, если за x не следует непосредственно y.

свойства экземпляра

  • RegExp.prototype.globalВключить ли глобальное сопоставление
  • RegExp.prototype.ignoreCaseИгнорировать ли регистр символов.
  • RegExp.prototype.lastIndexПозиция индекса строки, с которой начинается следующее совпадение.
  • RegExp.prototype.multilineВключить ли сопоставление многострочного шаблона (влияет на поведение ^ и $).
  • RegExp.prototype.sourceТекст исходного шаблона обычного объекта.
  • RegExp.prototype.stickyВключить ли закрепленное сопоставление.

метод экземпляра

  • RegExp.prototype.exec()Выполните обычную операцию сопоставления с целевой строкой.
  • RegExp.prototype.test()Проверьте, может ли текущее регулярное выражение соответствовать целевой строке.
  • String.prototype.match(pattern)согласно сpatternРегулярно сопоставляйте строку и возвращайте массив совпадающих результатов, если совпадения нет, возвращайтеnull
  • String.prototype.replace(pattern, replacement)согласно сpatternВыполните регулярное сопоставление и замените результат сопоставления наreplacement, возвращает новую строку

настоящий бой

изменить структуру текста

var re = /(\w+)\s(\w+)/
// \w 匹配 [A-Za-z0-9_]
// + 重复一次或更多次
// \s 匹配 空格符
// () 捕获括号
var str = "John Smith"
var newstr = str.replace(re, "$2, $1")
// $1: 捕获的值为 John 
// $2: 捕获的值为 Smith
console.log(newstr) //  转换后为 "Smith, John"

Обучение 1: Пожалуйста, передайте регулярное выражение, поставьте() => 1+1превратиться вfunction () { return 1+1 }

многострочное совпадение

var s = "Please yes\nmake my day!";
s.match(/yes.*day/);
// . 符号默认不匹配 \n
// 可以改为 /yes.*day/s ,使用 s 标识符来匹配多行
// 返回 null

s.match(/yes[^]*day/);
// ^ 匹配字符串的开始
// [^]* 表示匹配任何字符,包括换行符
// 返回 yes\nmake my day

Тренинг 2. Используйте регулярные выражения, чтобы получитьab a\nb abсерединаa\nbнить

Используйте регулярные выражения с пометкой «липкий»

var text = "First line\nsecond line";
var regex = /(\S+) line\n?/y;
// () 捕获括号
// \S+ 匹配一次或更多次非空白符
// \n? 匹配零到一次换行符
var match = regex.exec(text);
console.log(match[1]);  // 匹配到 First
// 输入 match[0] 返回的是 First line\n 所要进行匹配的文本
console.log(regex.lastIndex); // 匹配到位置 11
var match2 = regex.exec(text);
console.log(match2[1]); // 匹配到 Second
console.log(regex.lastIndex); // 匹配到位置 22

var match3 = regex.exec(text);
console.log(match3 === null); // 返回 true, 没有匹配到结果

Тренировка 3: С текстом"price: 10¥\nprice: 20¥\nprice: 30¥", пожалуйста, получите значение цены и сохраните его в массиве, вывод результата['10', '20', '30']

соответствующая ссылка

Извлечь значение переданного параметра ссылки

// 提取 str 的 name 和 age
var str = 'https://www.baidu.com?name=jawil&age=23'
// 获取name的值
var regName = /\?name=([^&]*)/
// \? 表示匹配 ? 字符,从该字符开始匹配
// name= 表示匹配 name= 的字符串
// [^&]* 表示匹配字符直到遇到 & 符号为止
// ([^&]*) 表示捕获匹配到的结果
// match 的值为 ["?name=jawil", "jawil"]
var match = regName.exec(str)
console.log(match[1]) // 返回 jawil

Тренинг 4: Измените регулярное выражение, чтобы получить значение атрибута age Как выглядит регулярное выражение?

форматирование чисел

Формат от 1 234 567 890 до 1 234 567 890

var str = '1234567890'
var reg = /\B(?=(\d{3})+(?!\d))/g
// \b 匹配单词的开始或结束
// \B 匹配单词的非开始和非结束的位置
//     \Bon 匹配 ' on' 为 null,即开头不能为 on
//     \Bon 匹配 ' onon' 为 on,匹配后一个 on
// (\d{3}+) 捕获1个或多个的3个连续数字
// (?!\d) 断言: 表示3个数字不允许后面跟着数字
// (\d{3}+)+(?!\d) 表示匹配的后边界跟着 3*n(n>=1)的数字.
// (?=) 断言: 表示后边必须跟着的内容
//     \B(?=(\d{3}+)+(?!\d)) 匹配非边界后跟着的3个数字

// 运行过程
// 第一次匹配到为 ["", "890"] 没有匹配到文本,但捕获到3个数字
// 替换后为 1234567,890
// 第二次匹配到为 ["", "567"]
// 替换后为 1234,567,890
// 第三次匹配到为 ["", "234"]
// 替换后为 1,234,567,890
// 最后一次运行结果为 null 替换结束
var format = str.replace(reg, ',')
console.log(format) // 1,234,567,890

Тренинг 5. Отформатируйте строку «255255255255» в формате IP-адреса «255.255.255.255» с помощью регулярных выражений.

Тренинг 6. Напишите регулярное выражение для проверки правильности входящего IP-адреса, например, входящего1.1.1.1вернуть true, передать1.1.1.257вернуть ложь

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

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

var str = 'ttabttdef'
var reg = /tt(?=ab)/
reg.exec(str)
// 匹配到的是 tt, 只有后面跟的是 ab 的才匹配
var reg1 = /tt(?=ab)ab/
reg1.exec(str)
// 匹配到的是 ttab, 断言只匹配位置, 所以断言匹配的这些字符会接下去进行匹配。
// 而不会因为被断言匹配过了就跳过这些字符。

Тренинг 7: Использование утверждений для сопоставления строк<div>red blue green</div>вводитьred blue green.

Тренинг 8: Используя утверждения, сопоставьте<xxx>任意字符串</xxx>середина任意字符串, где xxx представляет имя тега, например, совпадение<div>adsasdfa<br>asdfsd</div>серединаadsasdfa<br>asdfsd

Парсинг виртуального DOM-тега

Чтобы построить виртуальный DOM в исходном коде Vue, сначала скомпилируйте шаблон в синтаксическое дерево AST, затем преобразуйте его в функцию рендеринга и, наконец, верните VNode (VNode — это виртуальный DOM-узел Vue).

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

var dom = `<div :class="c" class="demo" v-if="isShow">{{item}}</div>`

// 匹配变量名
const variable = /[a-zA-Z_][\w\-\.]*/
// 匹配标签名
const tagName = /^<([a-zA-Z_][\w\-\.]*)/
console.log(tagName.exec(dom)[1])// 返回 div
// 匹配属性
const attr = /\s*([^\s'"<>/=]+)(?:=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+))/g
// \s*([^\s'"<>/=]+) 匹配属性名
// (?:=) 匹配赋值号 = 
// (?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)) 匹配属性值,包括 ""、 '' 和其它形式
var res = attr.exec(dom)
console.log(res[1]) // 返回 :class
console.log(res[2]) // 返回 "c"
// 匹配 {{}} 里的内容
const val = /{{(.*)}}/ 
console.log(val.exec(dom))// 返回 item

Отвечать

Тренировка 1:

var str = '() => 1+1'
var reg = /(\(\))\s(=>)\s([^]*)/
var str1 = str.replace(reg, 'function $1 { return $3 }')

Тренировка 2:

var s = "ab a\nb ab"
s.match(/a\nb/)

Тренировка 3:

var str = 'price: 10¥\nprice: 20¥\nprice: 30¥'
var reg = /\D*(\d+)/y
var a = []
while((match = reg.exec(str)) !== null) {
  a.push(match[1])
}
console.log(a)

Тренировка 4:

var str = 'https://www.baidu.com?name=jawil&age=23'
var regAge = /\&age=([^&]*)/
var match = regAge.exec(str)

Тренировка 5:

var pattern = /\B(?=(\d{3})+(?!\d))/g
var str = '255255255255'
str.replace(pattern, '.')

Тренировка 6:

  • Первое, что должно соответствовать, это 0 ~ 255
  • Матч 50 на 55:5[0-5]{1}
  • Совпадение 0 ~ 49:[0-4]\d{1}
  • Совпадение 200 ~ 255:2(5[0-5]{1}|[0-4]\d{1})
  • Совпадение 0 ~ 199:[0-1]?\d{1,2}
  • Точное совпадение 0 ~ 255:
    • (2(5[0-5]{1}|[0-4]\d{1})|[0-1]?\d{1,2})

Регулярное выражение в сочетании с обнаруженным ip

var reg1 = /(2(5[0-5]{1}|[0-4]\d{1})|[0-1]?\d{1,2})\.(2(5[0-5]{1}|[0-4]\d{1})|[0-1]?\d{1,2})\.(2(5[0-5]{1}|[0-4]\d{1})|[0-1]?\d{1,2})\.(2(5[0-5]{1}|[0-4]\d{1})|[0-1]?\d{1,2})/
// 把后边3段检测代码进行简化后
var reg2 = /(2(5[0-5]{1}|[0-4]\d{1})|[0-1]?\d{1,2})(\.(2(5[0-5]{1}|[0-4]\d{1})|[0-1]?\d{1,2})){3}/

Тренировка 7:

var str="<div>red blue green</div>"
var reg = /<div>(.*)(?=<)/
reg.exec(str)[1] // red blue green

Тренировка 8:

var str = '<div>asdas<br>dfadfsdasdf</div>'
var reg = /^<(\w+)>(.*)(?=<\/\1>)/
reg3.exec(str)[2] // asdas<br>dfadfsdasdf

использованная литература