Регулярные выражения просты, но для их освоения требуется много времени.
Общие символы
В регулярных выражениях необходимо помнить множество символов, вот наиболее часто используемые символы и их значения:
Общие совпадающие символы | имея в виду |
---|---|
[0-9] | соответствует одной цифре 0-9 |
[a-z] | соответствует одной строчной букве |
[A-Z] | соответствует одной заглавной букве |
\s | Совпадение со всеми пробельными символами, такими как пробелы, символы новой строки и т. д. |
\n | соответствует всем новым строкам |
\b | Сопоставьте границы между словами (соответствуйте последовательным буквам, обеим сторонам цифр) |
\w | Совпадение с любой буквой, цифрой, символом подчеркивания |
\d | Эквивалент [0-9] |
Специальные символы | имея в виду | Применение |
---|---|---|
^ | 1. Совпадать с начальной позицией входной строки 2. При использовании в [] означает не | 1. /^http/ Соответствовать строкам, начинающимся с http 2./[^a-zA-Z]/ сопоставить не буквы |
$ | Совпадение с концом входной строки |
/.com$/ соответствует строкам, оканчивающимся на .com |
| | Выберите одно из двух, означает или |
/a|b/ соответствует a или b |
. | Десятичная точка соответствует любому одиночному символу, кроме новой строки \n |
/./ соответствует символам, отличным от новой строки |
[] | Скобки соответствуют символу |
/[aeiou]/ соответствует одной из букв aeiou |
() | Круглые скобки указывают на группировку подвыражений | Совпавшее подвыражение можно использовать позже |
{} | Фигурные скобки указывают, сколько раз нужно уточнить выражение. | {n} соответствует n раз; {n,} соответствует как минимум n раз; {n, m} соответствует n-m раз |
+ | соответствует предыдущему подвыражению один или несколько раз |
/[0-9]+/ соответствует числу или числам |
* | соответствует предыдущему подвыражению ноль или более раз |
/[0-9]*/ Совпадение 0 или более цифр |
? | 1. Сопоставьте предыдущее подвыражение ноль или один раз 2. Укажите нежадный квалификатор | 1. /[0-9]?/ 2. /<.*?>/ соответствует тегу, например<p>
|
Экранирование необходимо для соответствия самим специальным символам, а именно:
* . ? + $ ^ [ ] ( ) { } | \ /
- в
/
Экранирование требуется в литералах, а не в конструкторах, как показано ниже, чтобы соответствовать косой черте./
.
const reg = /\//
const reg = new RegExp('/')
- Возьмите escape-символ в литерал
\
Использование конструктора для записи с двумя escape-символами\\
, который соответствует строке следующим образом.
.
const reg = /\./
const reg = new RegExp('\\.')
Общий метод
Регулярные выражения в js делятся на два типа: литералы и конструкторы:
// 字面量
const reg = /[0-9a-z]/g
// 构造函数
const reg = new RegExp('[0-9a-z]', 'g')
Там, где литералы не могут содержать переменных, в конструкторах можно использовать переменные:
const name = '幻灵尔依'
const reg = new RegExp(`我的名字叫${name}`)
часто используемыеreg.test(str)
метод, чтобы определить, соответствует ли регулярное выражение в строке:
const reg = /[0-9]/
const str = '文本中有没有数字1234等'
if (reg.test(str)) {
...
}
также часто используетсяstr.replace(reg, '')
метод замены содержимого строки:
const reg = /[0-9]/g
const str = '文本中的数字1234全部替换成x'
const newStr = str.replace(reg, 'x')
также использоватьstr.match(reg)
метод для получения соответствующего контента (вы также можете использоватьreg.exec(str)
):
const reg = /[0-9]+[.][0-9]+[.][0-9]+/g
const str = '这里有个表名字叫做 11.11.11'
str.match(reg) // ['11.11.11']
- Регулярные выражения в соответствии Если используется флаг g, будут возвращены все результаты, соответствующие полному регулярному выражению, но захваченные группы не будут возвращены.
- Если флаг g не используется, возвращается только первое полное совпадение и связанная с ним группа захвата (массив). В этом случае возвращаемый элемент будет иметь дополнительные свойства, как описано ниже.
Лао-цзы сказал: Суть заключается в следующем.
Жадный и нежадный
Квалификаторы * и + являются жадными и будут соответствовать как можно большему количеству литералов. Добавьте ? после них для нежадного или минимального соответствия.
- Жадный (по умолчанию все жадные)
const str = '<h1>正则表达式</h1>'
const reg = /<.*>/
str.match(reg) // ['<h1>正则表达式</h1>']
- нежадный
const str = '<h1>正则表达式</h1>'
const reg = /<.*?>/
str.match(reg) // ['<h1>']
Захват группировки и обратных ссылок
Круглые скобки()
Совпадающие подвыражения будут кэшироваться как группы для удобства использования в дальнейшем. Предположим, вы хотите получить тег h1 в html:
- Используйте \n в регулярном выражении для ссылки на n-ю группу захвата
const str = '<p>正则表达式</p><h1>正则表达式</h1><h2>正则表达式</h2>'
const reg = /<(h1)>.+?<\/\1>/
str.match(reg) // ['<h1>正则表达式</h1>']
- Использование вне регулярных выражений
$n
Ссылка на n-ю группу захвата (RegExp.$n)
const str = 'abc'
const reg = /(abc)/
RegExp.$1 // 'abc'
str.replace(reg, '$1$1') // 'abcabc'
Группировка без захвата и квалифицированный поиск
потому что группы захвата()
Каждый захваченный результат кэшируется для справки, поэтому увеличивается использование памяти. Если вы просто хотите использовать исходную функциональность группировки без кэширования, вы можете использовать группировку без захвата(?:)
const str = 'abc'
const reg = /(?:abc)/
RegExp.$1 // ''
Группы без захвата также имеют(?=)、(?<=)、(?!)、(?<!)
, они есть(?:)
Ограничений больше, то есть только сопоставление, а не вывод.
поиск вперед
Прямой поиск используется для ограничения суффиксов.
-
(?=)
: то есть найти квалифицированное условие(?=)
предыдущее совпадение (вывод не включает(?=)
совпадает)
const str = 'a.png b.jpg c.gif d.svg'
// 查找所有 边界开头的、 .svg 前面的 小写字母。
const reg = /\b[a-z](?=.svg)/g
str.match(reg) // ['d']
-
(?!)
: т.е. найтинесовместимыйКвалификация(?!)
предыдущее совпадение (вывод не включает(?!)
совпадает)
const str = 'a.png b.jpg c.gif d.svg'
// 查找所有边界开头的、 非.svg 前面的、 `.[a-z]{3}` 前面的 小写字母。
const reg = /\b[a-z](?!.svg)(?=\.[a-z]{3})/g
str.match(reg) // ['a', 'b', 'c']
обратный поиск
Обратный просмотр используется для ограничения префикса.
- Найти совпадения
(?<=)
последующих совпадений (вывод не включает(?<=)
совпадает)
const str = '1. 1111; 2. 2222; 3. 3333; 4. 4444。'
// 查找所有 序号 后面的项。
const reg = /(?<=\b[0-9]+\.\s).+?[;。]/g
str.match(reg) // ["1111;", "2222;", "3333;", "4444。"]
- найтинесовместимыйКвалификация
(?<!)
последующих совпадений (вывод не включает(?<!)
совпадает)
const str = 'a.png b.jpg c.gif d.svg'
// 查找前缀不为 a b c 的后面的项
const reg = /\b(?<![abc]\.)[a-z]{3}/g
str.match(reg) // ['svg']
получить некоторые съедобные каштаны
Как правило, более сложные обычные правила используются несколькими правилами одновременно. Вот несколько примеров:
Используйте прямой поиск и обратный поиск вместе:
Предположим, вы хотите получить<img crossorigin src="https://abcdefg.com" data-img-url="https://test.com">
серединаdata-img-url
ссылка в свойствах. Не вызывает сомнений то, что левая сторона ссылки должна бытьdata-img-url="
, правая сторона должна быть близко к"
(не жадный).
const str = '<img crossorigin src="https://abcdefg.com" data-img-url="https://test.com">'
const dataImgUrl = 'data-img-url'
const reg = new RegExp(`(?<=${dataImgUrl}=").+?(?=")`, 'g')
str.match(reg) // ['https://test.com']
Обратная ссылка и нежадное использование
Допустим я хочу получить кусок текста в html, но не хочу его добавлятьnot-show-in-text
Текст в метке тега может быть таким:
const notShowInText = 'not-show-in-text'
const html = `
<p>test1</p>
<p ${notShowInText} style="text-align: center;">
<b>表 1.4.4 测试表格</b>
</p>
<p>test2</p>
`
const reg = new RegExp(`<([a-z][a-z1-6]*?)[^>]+${notShowInText}[\\s\\S]+?</\\1>`, 'g')
const text = html.replace(reg, '').replace(/<[^>]+>/g, '')
Самое главное - соответствоватьnot-show-in-text
всю этикетку, где она находится.([a-z][a-z1-6]*?)
соответствует нежадному имени тега,[^>]
обещать<
прибыть>
наполовину заполненная этикетка,</\\1>
соответствует закрытому тегу,[\\s\\S]+?
Соответствует любому элементу, который может появиться в теге, и не является жадным.
Второй параметр replace может быть функцией обратного вызова.
Например, хотитеyyyy-mm-dd
отформатировать, заменить наmm/dd/yyyy
Как это сделать?
var regex = /(\d{4})-(\d{2})-(\d{2})/;
var string = "2017-06-12";
var result = string.replace(regex, "$2/$3/$1");
console.log(result); // "06/12/2017"
где замена используется во втором параметре$1、$2、$3
Относится к соответствующей группе. эквивалентна следующей форме:
var regex = /(\d{4})-(\d{2})-(\d{2})/;
var string = "2017-06-12";
var result = string.replace(regex, function() {
return RegExp.$2 + "/" + RegExp.$3 + "/" + RegExp.$1;
});
console.log(result); // "06/12/2017"
также эквивалентно:
var regex = /(\d{4})-(\d{2})-(\d{2})/;
var string = "2017-06-12";
var result = string.replace(regex, function(match, year, month, day) {
return month + "/" + day + "/" + year;
});
console.log(result); // "06/12/2017"
Вопрос интервью о компании
Для достижения преобразования тысячных: 12345678 12.345.678 после преобразования
Когда я впервые столкнулся с этой проблемой, я не ожидал, что для ее решения потребуется использовать обычную строку кода. Вместо этого я сначала преобразовал массив, затем перевернул его, затем разделил на три на три и, наконец, преобразовал его в строку. Хотя это может быть достигнуто, код является избыточным.
Позже я случайно увидел этот вопрос в вопросах интервью компании, и ответ был очень простым. Очень стыдно -_-||
-
12345678..toLocaleString('de-DE')
// Немецкая локализация отделяется ' . ', обычно разделяется ' , ' -
'12345678'.replace(/\B(?=(\d{3})+(?!\d))/g, '.')
Демонтаж:
-
\b соответствует границам слов, \B соответствует границам не слов, а числа не являются границами слов. '1234'.replace(/\B/g, '.') Результат: '1.2.3.4'
-
(?=) поиск вперед с ограничениями в скобках
-
(\b{3})+ соответствует трем составным символам один или несколько раз
-
(?!\d) Ограничение (\b{3})+ не может сопровождаться числами. Например, в этом примере за 678 и 345678 должны следовать не числа
Четвертый шаг можно заменить на \b или $ и т.д., ограничить конец, т.е.'12345678'.replace(/\B(?=(\d{3})+\b)/g, '.')
'12345678'.replace(/(\d)(?=(\d{3})+\b)/g, '$1.')
Этот метод сопоставляет предыдущую цифру трех соединительных символов и заменяет ее на «.» после нее.