Интервьюер! Поговорим о регулярности

внешний интерфейс регулярное выражение опрос

Кратко

Регулярные выражения — мощный инструмент для обработки строк и повышения эффективности работы.Хорошее регулярное выражение может сэкономить нам десятки или даже сотни строк кода. На работе вы можете увидеть много регулярных строк обработки, появляющихся в коде, или вы можете увидеть, что в коде нет регулярности Причина в том, что люди, которые знают регулярность, часто думают об использовании регулярности для обработки строк в первую очередь. множество API. А во время собеседования многие студенты часто зависают здесь на регуляре, так что для фронтенд регуляра это необходимый навык. Эта статья может не только научить вас, как его использовать, но и позволит вам понять принцип, и вы будете бесстрашны в будущем использовании и интервью.

1. Основы

Чтобы играть регулярно, вы должны сначала понять три элемента:修饰符 元字符 量词
Пример: var reg = /^\d$/g Это простой регуляр, давайте подробнее рассмотрим три элемента

1. Модификаторы

  • g- глобальное глобальное сопоставление (пока есть успешный результат сопоставления, он будет совпадать до тех пор, пока его не будет)
  • i- ignoreCase игнорировать регистр
  • m- многострочное многострочное совпадение

2. Мета-персонажи

Метасимволы делятся на специальные метасимволы и обычные метасимволы.
Обычные метасимволы — это элементы, включенные в массивы, буквы и т. д.
Общие специальные метасимволы:

  • \Экранирующий символ (преобразование обычного символа в специальный символ или преобразование значимого символа в обычный символ)
  • .Любой символ, кроме \n (новая строка)
  • \dсоответствует числу от 0 до 9
  • \DСопоставьте число, которое составляет не от 0 до 9 (комбинация прописных и строчных букв - противоположное значение
  • \wСоответствует символу от 0 до 9, букве или _
  • \sсоответствует произвольному пробельному символу
  • \bсоответствовать разделителю
  • x|yсоответствует либо x, либо y
  • [a-z]соответствует любому символу от az
  • [^a-z]соответствует любому символу, кроме a-z
  • [xyz]Совпадение x или y или z символа
  • [^xyz]напротив выше
  • ()Вся малая группа, соответствующая небольшой группе (можно понимать как маленькую завсегдатая в большом завсегдатае)
  • ^начинается с метасимвола
  • $заканчивается метасимволом
  • ?:только совпадение без захвата
  • ?=Положительный позитивный прогноз
  • ?!положительный отрицательный взгляд вперед

3. Квантификаторы

Основная функция квантификаторов — описать количество вхождений метасимволов следующим образом:

  • +заставить предыдущий метасимвол появляться один или несколько раз
  • ?Встречается от нуля до единицы
  • *Встречается от нуля до многих раз
  • {n}появляется n раз
  • {n,}N, чтобы появиться несколько раз
  • {n,m}Встречается от n до m раз

Увидев это, у всех должно слегка закружиться голова. Как использовать эти странные символы? Ниже показано, как использовать эти символы. Прежде чем использовать их, учащиеся должны помнить об этих символах. Если вы хотите играть с регулярностью, то что вы нужно помнить их, и когда вы помните эти символы, вы уже начинаете.

2. Мета-персонажи

  • 1. Запустить метасимвол^

    Метасимволы, соответствующие разоблачениям, например:var reg = /^2/;Указывает, что начало должно быть 2, если начальный метасимвол помещен в [] Пример: [^] указывает на противоположное значение в случае неквадратных скобок.

  • 2. Конечный метаморфизм$

    Соответствует метасимволу в конечной позиции, например:var reg = /2$/;означает, что конец должен быть 2, если этоvar reg = /^2$/;Представление может быть только 2, потому что 2 представляет только метасимвол.

  • 3. Экранирующие символы\

    Преобразование специальных метасимволов в обычные символы, например:var reg = /^2.3$/Нормальное понимание состоит в том, что соответствующее откровение — это 2, конец — 3, а середина —.Регулярно, но там.Относится к специальным метасимволам, то есть помимо\n(новая строка), так что если это 2.3/2+3/2s.3 и т.д., пока это не ·\nВсе совпадают успешно, поэтому для этого требования используются escape-символы.\А именно: var reg = /^2\.3$/ преобразует специальные метасимволы.сбежать в реальность.элемент, только 2.3 может снова успешно сопоставиться.Думайте следующим образом:

    var reg1 = /^\d$/
    var reg2 = /^\\d$/
    var reg3 = /^\\\d$/
    var reg4 = /^\\\\d$/
    

    Во-первых, reg1 представляет число от 0 до 9, поэтому 0-9 можно успешно сопоставить.
    reg2 появляется два\Независимо от того, 0-9 ли это d \ d совпадение не удается, только\\dСовпадение успешно, потому что первый экранирующий символ преобразует второй\Побег в нормальное состояние\, то первый\Также представляет обычные символы, поэтому соответствует только до\\dвступить в силу
    reg3 появляется три\, то все так и будут думать\\\dправильный ответ, нет, правильный ответ на данный момент\\[0-9]Означает \ и любое число от 0 до 9, причина в том, что первый\Побег второй, так что становится\\ \dделится на две части,\\Для обычных персонажей,\dпредставляет собой число от 0 до 9, поэтому правильный ответ\\[0-9]
    reg4 появляется четыре\Многие студенты считают, что правильный ответ должен быть\\\[0-9], к сожалению, верно\\\\d, причина в том, что когда первый экранирует второй в нормальный символ, третий экранирует четвертый в нормальный символ, поэтому окончательное совпадение\\\\d
    Увидев это, я думаю, что у некоторых моих друзей уже закружилась голова. Хотя мы не будем играть в такую ​​​​операцию на работе, мы должны иметь глубокое понимание escape-символов. Если вы пишете var reg = /^$/ прямо в регулярное выражение, будет сообщено об ошибке, потому что регулярное выражение не может быть одним\появляется, потому что он является особым метасимволом и его нужно написать не менее двух\, например:var reg = /^\\$/Правильное совпадение'\\', так что имейте в виду два\представлять реальный\, студенты, которые понимают здесь, я считаю, что символы побега были полностью освоены.

  • 4. Или метасимволыx|y

    Этот метасимвол хорошо понимается, чтобы соответствовать x или соответствовать y, нет никакой сложности, например:

    var reg = /2|3/
    // 匹配数字为2或者为3
    
  • 5. Небольшие группы()

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

    var reg = /^18|19$/
    
    // 这个例子很多同学能够了解是18或者19开头 但是结尾呢?真的只匹配19么? 其实并不是
    // 正确的匹配除了18 19 还有181、189、819 这时候小分组就起到了作用如下
    
    var reg = /^(18|19)$/
    
    // 这里将18或19用()包裹起来,起到小分组的作用
    // 这样这个正则只匹配18开头结尾或者19而不是181和189
    
  • 6. Цитаты группы\n

    Концепция группировки ссылок заключается в том, что вы можете ссылаться на маленькие регулярные правила, указанные в больших регулярных правилах, например:

    var reg = /^([a-z])([a-z])\2([a-z])$/
    // 符合的字符串:book week http ...​
    

    В частности, приведенный выше пример понимается как\2Представляет собой полную ссылку на второе маленькое регулярное правило, которое совпадает со вторым малым обычным правилом.([a-z])То же самое, может уменьшить сложность обычных и иметь дело с повторяющимися правилами

  • 7. Сопоставьте символы[]

    [xyz],[^xyz],[a-z],[^a-z]Ниже приведен небольшой пример для понимания учащимися.

    var reg = /^[a-zA_Z0-9_]$/
    // 这个正则和等价于\w 就是匹配一个0~9或字母或_之间的一个字符
    // 而正则[xyz]中的xyz分别代表a-z、A_Z、0-9,xyz只是一个代表标识,可以有xyzhw各种组合
    // 就像这个例子中有下划线_一样四个的匹配
    // 有一个重点补充,在[]中的特殊元字符一般都代表本身含义,如下
    var reg = /^[.?+&]$/
    // 代表着匹配. .? ?+ ...等等
    
  • 8. Пограничный характер\b

    Соответствие границе слова, то есть положению между словом и пробелом (границей в основном являются левая и правая части слова) Например:

    var reg = /er\b/
    // 可以匹配never中的er,但是不能匹配verb中的er
    var reg = /\b\w+\b/g
    // 能匹配字母数字和下划线与单词边界 'my blog is www.ngaiwe.com'
    // 能匹配 'my'、'blog'、'is'、'www'、'ngaiwe'、'com'
    
  • 9. Матч только без захвата?:

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

    var reg = /^(\d{6})(\d{4})(\d{2})(\d{2})\d{2}(\d)(\d|X)$/g
    var str = '110105199001220613'
    console.log(reg.exec(str))
    // 打印结果为 "110105199001220613", "110105", "1990", "01", "22", "1", "3"
    
    var reg = /^(\d{6})(?:\d{4})(\d{2})(\d{2})\d{2}(\d)(\d|X)$/g
    // 打印结果为 "110105199001220613", "110105", "01", "22", "1", "3"
    // 会将第二个小分组只匹配,不捕获
    
  • 10. Положительная положительная предварительная проверка?=

    Эту концепцию сложнее понять, она используется для проверки того, соответствует ли элемент, следующий за элементом, соответствующему правилу, но не использует это правило. Пример 1:

    var reg = /windows(?=95|98|NT|2000)/
    var str1 = 'windows2000'
    var str2 = 'windowsxp'
    
    console.log(reg.test(str1))
    console.log(reg.test(str2))
    // str1 为true str2 为false
    
    console.log(reg.exec(str1))
    console.log(reg.exec(str2))
    // 能捕获到str1 并且捕获结果时windows 并没有将2000也同时捕获
    // 说明正向预查只负责匹配相应规则
    

    Пример 2:

    var reg1 = /win(?=d)dows/
    var reg2 = /win(d)dows/
    var str = 'windows'
    console.log(reg1.test(str))
    console.log(reg2.test(str))
    // reg1 返回true reg2返回 false
    // 原因是正向预查只负责匹配,不消耗字符,也就是并不会匹配为里面规则的字符
    // reg1 相当于匹配windows并且符合win后面第一个出现的是d
    // reg2 相当于匹配winddows
    
  • 11. Просто хочу отказаться от предварительной проверки?!

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

3. Два способа создания регулярного

Есть два способа создать регулярку: один — буквальное создание, а другой — создание конструктора.

  • 1. Буквальное создание

var reg = /\d+/img

  • 2. Создание конструктора

var reg = new RegExp('\\d+', 'img')Первый параметр является метасимволом, а специальный символ \d в нем является обычным символом, поэтому его нужно экранировать как специальный символ с помощью \, а второй параметр является модификатором.

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

var stringMode = 'string'
var reg = new RegExp(`^\\[object ${stringMode}\\]$`)
console.log(reg.toString())

4. Обычный метод прототипа

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

正则原型对象方法

Вы можете видеть, что в обычном объекте-прототипе всего три метода:exec testа такжеtoString

  • 1.execЭтот метод в основном предназначен для захвата групп, а фактическим параметром является строка, которая должна быть сопоставлена. как показано на рисунке:

    正则原型对象方法

    принцип захвата

    • 1. При захвате сначала проверить, соответствует ли текущая строка обычной, если нет, вернуть null (ничего не захватывается)
    • 2. Если совпадение начинается с крайнего левого конца строки, найдите совпадающее содержимое справа и верните совпадающее содержимое.

    Зафиксировать результаты

    • 1. Результат — массив
    • 2. Первый элемент 0 — это результат текущего совпадения в этом большом регулярном
    • 3.indexэто позиция индекса совпадающего результата в строке
    • 4.inputНеобработанная строка текущей обычной операции
    • 5. Если есть группировка в большом регулярном()Полученный массив - это каждый небольшой пакет со второго запуска результатов захвата.
    • Ниже приведен пример удостоверения личности для удобства использования, ниже будет специально введено отдельное правило сопоставления, что означает здесь только полевое исследование.

    正则exec方法

  • 2. Лень

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

    Решение

    Добавьте модификатор g в конце обычного (глобального) совпадения.

    принцип

    Как показано на рисунке, сам регуляр обладает свойствомlastIndexНачальный индекс следующего регулярного выражения в строке
    Значение по умолчанию равно 0, и поиск начинается с первой позиции строки, видно, что при выполнении execlastIndexне изменился, и даже если вручную изменитьlastIndexтоже не работает, браузер его не распознает

    正则exec方法
    正则exec方法

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

    正则exec方法
    正则exec方法

    Давайте вручную создадим функцию для сопоставления всего и зафиксируем ее следующим образом:

    var reg = /^(\d{6})(\d{4})(\d{2})(\d{2})\d{2}(\d)(\d|X)$/g
    var str = '110105199001220613'
    
    RegExp.prototype.myExec = function myExec() {
    	var str = arguments[0] || ''
    	var result = []
    	// 首先this指向的是RegExp,所以判断this是否加了全局修饰符g
    	// 如果没有,防止执行死循环,我们只执行一次exec并将其返回即可
    	
    	if(!this.global) {
    		return this.exec(str)
    	}
    	
    	var arrs = this.exec(str)
    	while(arrs) {
    		result.push(arrs[0])
    		// 此时lastIndex的值已经变为上一次的结尾
    		arrs = this.exec(str)
    	}
    	return result
    }
    

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

  • 3.testЭтот метод в основном используется для регулярного сопоставления, конечно, его также можно использовать для захвата

    Сопоставление с левой стороны строки, сопоставление символов, соответствующих обычным правилам, возврат true, в противном случае возврат false, то же самоеtestТакже изменен модификатором glastIndexзначение

    использоватьtestосуществлять захват

    var reg = /\{([a-z]+)\}/g
    var str = 'my name is {weiran}. I am from {china}'
    var result = []
    while (reg.test(str)) {
    	result.push(RegExp.$1)
    }
    console.log(result)
    // ['weiran', 'china']
    

    Когда тест соответствует до конца или не соответствует, возвращает false, в случае успеха добавляет текущую небольшую группу в массив, чтобы соответствовать содержимому первого элемента существует в конструкторе RegExp$1-$9, они конкретно относятся к контенту, захваченному совпадениями с первого по девятое текущей малой группы.

  • 4.toString

    заключается в преобразовании регулярного выражения в строку

5. Метод регуляризации струн

  • 1.match

    Такой же метод захвата, как показано на рисунке:

    正则match方法

    Когда модификатор g добавлен, он возвращает массив, состоящий из результатов сопоставления большой регулярности.Метод, написанный выше, если вы хотите вернуть тот же результат при добавлении модификатора g, он такой же, как если бы он не был добавлено, поэтому используйте его напрямуюmatchспособ захвата всего соответствующего контента. Но у него также есть ограничения.Как упоминалось выше, при добавлении модификатора g содержимое захвата небольшой группы будет игнорироваться, а будет захвачено только большое содержимое обычного захвата.Решение такое же, как и выше myExec, изменить arr[ 0] в arr каждый раз, когда результат совпадает, каждая небольшая группа также сохраняется.

  • 2.replace

    В основном используется при замене, где есть два параметра, первый — это заменяемая строка или обычный, а второй — замещающий контент или функция возврата.Конкретные операции заключаются в следующем:

    var str = 'my name is {weiran}, my blog is {ngaiwe}'
    var reg = /\{([a-z]+)\}/
    str = str.replace(reg, '123')
    console.log(str)
    // 打印出 my name is 123, my blog is {ngaiwe}
    // 同学们会发现和exec的懒惰性很相似,不加修饰符g 只匹配第一个lastIndex没有改变
    
    var reg = /\{([a-z]+)\}/g
    // 打印出 my name is 123, my blog is 123
    

    и заменить не изменяет исходную строку

    正则replace方法

    var str = 'my name is {weiran}, my blog is {ngaiwe}'
    var reg = /\{([a-z]+)\}/g
    str = str.replace(reg, function () {
    	console.log(arguments)
    })
    // 打印出当前匹配的小分组,如果函数中没有return出替换值,则返回undefined
    
  • 3.split

    Его можно разбить на массивы обычным способом.Конкретные примеры таковы:

    var str = 'weiRanNgaiWe'
    var reg = /[A-Z]/
    console.log(str.split(reg))
    // ["wei", "an", "gai", "e"]按照大写拆分成数组
    
  • 4.search

    похожий наindexOf, возвращает начальную позицию совпавшего элемента, если не возвращает -1, модификатор g не поддерживается

    var str = 'ngaiwe@126.com'
    var reg = /\d+/
    console.log(str.search(reg))
    // 返回 7
    

6. Анализ реальных дел

  • 1. Идентификационный номер

    Пример удостоверения личности: 110105199109214237
    Согласно этому анализу, первые 6 цифр состоят из кода региона, затем четыре цифры — это год, два месяца, два дня и четыре случайные цифры, предпоследняя цифра — мужской, четный пронумеровано женщиной, а последняя цифра может быть заглавной X, поэтому регулярное выражение в соответствии с этим правилом

    var str = '110105199109214237'
    var reg = /^(\d{6})(\d{4})(\d{2})(\d{2})\d{2}(\d)(\d|X)$/
    console.log(reg.exec(str))
    // ["110105199109214237", "110105", "1991", "09", "21", "3", "7", index: 0, input: "110105199109214237", groups: undefined]
    
  • 2. Почтовый ящик

    Пример электронного письма: weiran@vipkid.com.cn
    Из этого анализа:
    1. Перед @ могут стоять цифры, буквы, знаки подчеркивания, -, . 2.- и.. не могут быть связаны между собой
    /^\w+((-|\w+)|(.\w+))*/ Начало должно состоять из цифр, букв или символов подчеркивания, а следующее содержимое может быть - и символы подчеркивания цифр и букв или . и символы подчеркивания цифры и буквы от 0 до нескольких символов
    3. @ задняя часть
    Во-первых, это должен быть многозначный символ, состоящий из цифр и букв.
    Затем может быть суффикс почтового ящика, состоящий из .или .и- из символов перед ссылкой.
    Наконец, это должен быть суффикс почтового ящика, состоящий из .

    var reg = /^\w+((-|\w+)|(\.\w+))*@[a-zA-Z0-9]+((\.|-)[a-zA-Z0-9]+)*\.[a-zA-Z0-9]+$/
    var str = 'weiran@vipkid.com.cn'
    console.log(reg.test(str))
    // true
    
  • 3. Перехват URL

    Например, взятый параметр URL:
    Woohoo. Год изменился на er.com/afraid/index. …
    Что нам нужно, так это пара значений ключа преобразования параметров и хеш-значение {имя: 'weiran', возраст: 27, пол: 0, HASH: 'develpoment'}
    Из этого анализа:
    Его необходимо захватить двумя частями: первый раз для захвата параметров после ?, а второй раз для захвата хеш-значения после #
    Сначала сопоставьте первый, его правило состоит в том, чтобы соответствовать обеим сторонам знака равенства, поэтому это /()=()/, и соответствовать специальным символам, кроме ?&=#, сохранить их в объекте obj
    Второй соответствует хешу, метод аналогичен первому, но соответствует части после #

    String.prototype.myQueryURLParameter = function myQueryURLParameter () {
    	var obj = {}
    	this.replace(/([^?&=#]+)=([^?&=#]+)/g, function () {
    		obj[arguments[1]] = arguments[2]
    	})
    	this.replace(/#([^?&=#]+)/g, function () {
    		obj['HASH'] = arguments[1]
    	})
    	return obj
    }
    

7. Резюме

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

8. Блог

Технологический блог Вэй Ран

Если у вас есть какие-либо вопросы, оставьте сообщение или отправьте письмо по адресу ngaiwe@126.com.

9. Поделиться

Обычная таблица метасимволов
Регулярный онлайн-инструмент тестирования