Javascript.RU

Особенности регулярных выражений в Javascript

Update: Более новый материал по этой теме находится по адресу https://learn.javascript.ru/regexp-specials.

Регулярные выражения в javascript немного странные. Вроде - перловые, обычные, но с подводными камнями, на которые натыкаются даже опытные javascript-разработчики.

Эта статья ставит целью перечислить неожиданные фишки и особенности RegExp в краткой и понятной форме.

Общую информацию о регулярных выражениях в javascript вы можете найти в статье Регулярные выражения.

Для поиска в многострочном режиме почти все модификации перловых регэкспов используют специальный multiline-флаг.

И javascript здесь не исключение.

Попробуем же сделать поиск и замену многострочного вхождения. Скажем, будем заменять [u] ... [/u] на тэг подчеркивания: <u>:

function bbtagit(text) {
  text = text.replace(/\[u\](.*?)\[\/u\]/gim, '<u>$1</u>')
 
  return text
}

var line = "[u]мой\n текст[/u]"
alert( bbtagit(line) )

Попробуйте запустить. Заменяет? Как бы не так!

Дело в том, что в javascript мультилайн режим (флаг m) влияет только на символы ^ и $, которые начинают матчиться с началом и концом строки, а не всего текста.

Точка по-прежнему - любой символ, кроме новой строки. В javascript нет флага, который устанавливает мультилайн-режим для точки. Для того, чтобы заматчить совсем что угодно - используйте [\s\S].

Работающий вариант:

function bbtagit(text) {
  text = text.replace(/\[u\]([\s\S]*)\[\/u\]/gim, '<u>$1</u>')
 
  return text
}

var line = "[u]мой\n текст[/u]"
alert( bbtagit(line) )

Это не совсем особенность, скорее фича, но все же достойная отдельного абзаца.

Все регулярные выражения в javascript - жадные. То есть, выражение старается отхватить как можно больший кусок строки.

Например, мы хотим заменить все открывающие тэги <a>. На что и почему - не так важно.

text = '1 <A href="#">...</A> 2'
text = text.replace(/<A(.*)>/, 'TEST')
alert(text)

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

Это происходит из-за того, что точка-звездочка в "жадном" режиме пытается захватить как можно больше, в нашем случае - это как раз до последнего >.

Последний символ > точка-звездочка не захватывает, т.к. иначе не будет совпадения.

Как вариант решения используют квадратные скобки: [^>]:

text = '1 <A href="#">...</A> 2'
text = text.replace(/<A([^>]*)>/, 'TEST')
alert(text)

Это работает. Но самым удобным вариантом является переключение точки-звездочки в нежадный режим. Это осуществляется простым добавлением знака "?" после звездочки.

В нежадном режиме точка-звездочка пустит поиск дальше сразу, как только нашла совпадение:

text = '1 <A href="#">...</A> 2'
text = text.replace(/<A(.*?)>/, 'TEST')
alert(text)

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

В javascript это сделать нельзя.. Вот такая особенность. А вопросительный знак после звездочки рулит - честное слово.

Иногда нужно в самом паттерне поиска обратиться к предыдущей его части.

Например, при поиске BB-тагов, то есть строк вида [u]...[/u], [b]...[/b] и [s]...[/s]. Или при поиске атрибутов, которые могут быть в одинарных кавычках или двойных.

Обращение к предыдущей части паттерна в javascript осуществляется как \1, \2 и т.п., бэкслеш + номер скобочной группы:

text = ' [b]a [u]b[/u] c [/b] '

var reg = /\[([bus])\](.*?)\[\//*u*/\1/*/u*/\]/
text = text.replace(reg, '<$1>$2</$1>')
alert(text)

Обращение к скобочной группе в строке замены идет уже через доллар: $1. Не знаю, почему, наверное так удобнее..

P.S. Понятно, что при таком способе поиска bb-тагов придется пропустить текст через замену несколько раз - пока результат не перестанет отличаться от оригинала.

Эти две задачи решаются в javascript принципиально по-разному.

Начнем с "простого".

Для замены всех вхождений используется метод String#replace.
Он интересен тем, что допускает первый аргумент - регэксп или строку.

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

Попробуйте:

alert("2 ++ 1".replace("+", "*"))

Каков результат? Как, заменился только один плюс, а не два? Да, вот так.

Чтобы заменить все вхождения, String#replace придется использовать в режиме регулярного выражения.

В режиме регулярного выражения плюс придется заэкранировать, но зато replace заменит все вхождения (при указании флага g):

alert("2 ++ 1".replace(/\+/g, "*"))

Вот такая особенность работы со строкой.

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

Следующий пример произведет операции вычитания:

var str = "count 36 - 26, 18 - 9"
str = str.replace(/(\d+) - (\d+)/g, function(a,b,c) { return b-c })
alert(str)

В javascript нет одного универсального метода для поиска всех совпадений.
Для поиска без запоминания скобочных групп - можно использовать String#match:

var str = "count 36-26, 18-9"
var re =  /(\d+)-(\d+)/g
result = str.match(re)
for(var i=0; i<result.length; i++) alert(result[i])

Как видите, оно исправно ищет все совпадения (флаг 'g' у регулярного выражения обязателен), но при этом не запоминает скобочные группы. Эдакий "облегченный вариант".

В сколько-нибудь сложных задачах важны не только совпадения, но и скобочные группы. Чтобы их найти, предлагается использовать многократный вызов RegExp#exec.

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

var str = "count 36-26, 18-9"
var re =  /(\d+)-(\d+)/g
var res
while ( (res = re.exec(str)) != null) {
  alert("Найдено " + res[0] + ":  ("+ res[1]+") и ("+res[2]+")")
  alert("Дальше ищу с позиции "+re.lastIndex)
}

Проверка while( (res = re.exec(str)) != null) нужна т.к. значение res = 0 является хорошим и означает, что вхождение найдено в самом начале строки (поиск успешен). Поэтому необходимо сравнивать именно с null.

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

Вот - одна интересная функция.

Запустите ее один раз, запомните результат - и запустите еще раз.

function rere() {
    var re1 = /0/, re2 = new RegExp('0')
    alert([re1.foo, re2.foo])
    re1.foo = 1
    re2.foo = 1
}
rere()

В зависимости от браузера, результат первого запуска может отличаться от второго. На текущий момент, это так для Firefox, Opera. При этом в Internet Explorer все нормально.

С виду функция создает две локальные переменные и не зависит от каких-то внешних факторов.

Почему же разный результат?

Ответ кроется в стандарте ECMAScript, пункт 7.8.5:

Цитата...

A regular expression literal is an input element that is converted to a RegExp object (section 15.10)
when it is scanned. The object is created before evaluation of the containing program or function begins.
Evaluation of the literal produces a reference to that object; it does not create a new object.

То есть, простыми словами, литеральный регэксп не создается каждый раз при вызове var r = /regexp/.
Вместо этого браузер возвращает уже существующий объект, со всеми свойствами, оставшимися от предыдущего запуска.

В отличие от этого, new RegExp всегда создает новый объект, поэтому и ведет себя в примере по-другому.

Есть еще особенности?

Напишите в комментарии, и я добавлю их в статью.


Автор: pgslot-games (не зарегистрирован), дата: 11 мая, 2022 - 09:56
#permalink

Mega Game Online Slot Game https://megagame.vegas/ The newest website 2021, the number 1 slot website

PG SLOT online slots game https://pgslot-games.co/ Sign up for a new account, get a 100% bonus, 1st place

PG SLOT online slots game https://pgslot-games.co/ Sign up for a new account, get a 100% bonus, 1st place


Автор: Marie Johannot (не зарегистрирован), дата: 16 мая, 2022 - 20:37
#permalink

Nous lib Learnalanguage


Автор: Molly Pehrson (не зарегистрирован), дата: 18 мая, 2022 - 20:36
#permalink

Автор: mp3 music (не зарегистрирован), дата: 20 мая, 2022 - 00:32
#permalink

It's a great article, thanks for sharing this information. Liteboxmusic


Автор: 온라인바카라 (не зарегистрирован), дата: 27 мая, 2022 - 05:39
#permalink

Which is some inspirational stuff. Never knew that opinions might be this varied. Thank you for all the enthusiasm to provide such helpful information here. 온라인바카라
xx


Автор: 먹튀 검증 (не зарегистрирован), дата: 15 июня, 2022 - 05:02
#permalink

If you have any questions about the safe eat-and-run guarantee company provided by Eat Tiger, please contact the customer center at any time!

We will recommend and introduce each Toto site that suits the characteristics of each company and members. Make high profits through our eating tiger. 먹튀 검증


Автор: 먹튀타이거 (не зарегистрирован), дата: 15 июня, 2022 - 05:04
#permalink

An intriguing discussion may be worth comment. I’m sure you should write much more about this topic. Scan Utility is an application that allows users to scan documents, photos, and more quickly. 먹튀타이거


Автор: aniss (не зарегистрирован), дата: 16 июня, 2022 - 15:04
#permalink

A very nice blog, I like the way IPTV Canada you share very honestly and interestingly, through my blog I learned a lot of things.


Автор: 마하캔디 (не зарегистрирован), дата: 20 июня, 2022 - 05:20
#permalink

Unbelievable!! The problem I was thinking about was solved. 마하캔디 You are really awesome.


Автор: 비아그라 (не зарегистрирован), дата: 24 июня, 2022 - 10:28
#permalink

It's very interesting. And it's fun. This is a timeless article. I also write articles related to , and I run a community related to 비아그라 . For more information, please feel free to visit !!


Автор: 비아그라 (не зарегистрирован), дата: 26 июня, 2022 - 05:33
#permalink

It's very interesting. And it's fun. This is a timeless article. I also write articles related to , and I run a community related to 비아그라 . For more information, please feel free to visit !!


Автор: 온라인카지노 (не зарегистрирован), дата: 29 июня, 2022 - 05:17
#permalink

I am contemplating this topic. I think you can solve my problems. My site is at " 온라인카지노 ". I hope you can help me.


Автор: 온라인카지노 (не зарегистрирован), дата: 29 июня, 2022 - 05:18
#permalink

I am contemplating this topic. I think you can solve my problems. My site is at " 온라인카지노 ". I hope you can help me.


Автор: ช่วยตัวเอง ให้มีเงิน Slot Pg (не зарегистрирован), дата: 29 июня, 2022 - 11:44
#permalink

ช่วยตัวเอง ให้มีเงิน Slot Pg เรามาลองมาดูกันว่าถ้าอยากมีเงินเก็บมากขึ้นเพื่อสร้างความมั่นคงให้กับชีวิต ทุกคนล้วนคาดหวังให้ตัวเองสุขสบาย ลอง slot pg มีกิน มีเงินใช้จนถึงวันสุดท้าย ของชีวิต


Автор: riches777 (не зарегистрирован), дата: 29 июня, 2022 - 11:48
#permalink

riches777 ค่ายเกมส์จาก slot pg อันดับหนึ่งของไทย รับเครดิตฟรี ไม่ติดเรื่องฝากขั้นต่ำ สามารถถอนได้ไม่จำกัด หรือ ฝากหลักร้อย แต่ถอนหลักล้าน


Автор: 비아그라 (не зарегистрирован), дата: 3 июля, 2022 - 11:46
#permalink

It's very interesting. And it's fun. This is a timeless article. I also write articles related to , and I run a community related to 비아그라 . For more information, please feel free to visit !!


Автор: MTBOSS (не зарегистрирован), дата: 4 июля, 2022 - 05:49
#permalink

I've seen some very helpful stuff.먹튀보스I found a lot of information, but your article was the most attractive and excellent. I will visit you often.


Автор: escort finden (не зарегистрирован), дата: 6 июля, 2022 - 19:35
#permalink

Spend some extratime and chat for free with hot sexy ladies on escort finden


Автор: 온라인바카라사이트 (не зарегистрирован), дата: 8 июля, 2022 - 06:31
#permalink

Your ideas inspired me very much. 온라인바카라사이트 It's amazing. I want to learn your writing skills. In fact, I also have a website. If you are okay, please visit once and leave your opinion. Thank you.


Автор: 해머캔디 (не зарегистрирован), дата: 10 июля, 2022 - 06:14
#permalink

Hello. I'm subscribed to your posts. You inspire me a lot. 해머캔디 I am so grateful.


Автор: 온라인바카라 (не зарегистрирован), дата: 12 июля, 2022 - 05:01
#permalink

Hello, I read the post well. 온라인바카라 It's a really interesting topic and it has helped me a lot. In fact, I also run a website with similar content to your posting. Please visit once


Автор: Lilla Szoke (не зарегистрирован), дата: 13 июля, 2022 - 20:39
#permalink

Rosszlányok azt ígéri, hogy megtalálja a legkeresettebb randikat bármely területen, és közvetlen hozzáférést biztosít a postaládájukhoz. Ez sok lábmunkát megspórolhat a randizás során. Nincs többé kocsmákban való kikezdősködés. Nincs többé tánc idegenekkel a klubokban. Nem kell többé azon tűnődnöd, hogy a szemközti cukiság érdeklődik-e irántad.


Автор: 바카라게임사이트 (не зарегистрирован), дата: 17 июля, 2022 - 09:19
#permalink

I'm so happy to finally find a post with what I want. 바카라게임사이트 You have inspired me a lot. If you are satisfied, please visit my website and leave your feedback.


Автор: Гость (не зарегистрирован), дата: 17 июля, 2022 - 11:24
#permalink

โปรโมชั่นยอดฝากแรกโบนัส ลองเล่นวันนี้ ambbet auto


Автор: 온라인카지노 (не зарегистрирован), дата: 18 июля, 2022 - 10:55
#permalink

While looking for articles on these topics, I came across this article on the site here. As I read your article, I felt like an expert in this field. I have several articles on these topics posted on my site. Could you please visit my homepage??? 온라인카지노


Автор: 비아그라 (не зарегистрирован), дата: 19 июля, 2022 - 07:29
#permalink

Are you the one who studies this subject?? I have a headache with this subject. 비아그라 Looking at your writing was very helpful.


Автор: https://megagame.game/ (не зарегистрирован), дата: 19 июля, 2022 - 18:42
#permalink

https://megagame.game/ Hello I am so delighted I located your blog, I really located you by mistake, while I was watching on google for something else, Anyways I am here now and could just like to say thank for a tremendous post and a all round entertaining website. Please do keep up the great work


Автор: สล็อตทดลองเล่นฟรี pg (не зарегистрирован), дата: 19 июля, 2022 - 18:43
#permalink

สล็อตทดลองเล่นฟรี pg I really really love this article. it helps me through a tough time. thanks


Автор: สล็อต (не зарегистрирован), дата: 19 июля, 2022 - 18:51
#permalink

สล็อต Try to play slots for free. It's real. It's really broken. Play all games for free. PG Slots


Автор: slot (не зарегистрирован), дата: 19 июля, 2022 - 18:52
#permalink

Slot Sign up today and receive a free bonus. Try the newest slots Hundreds of games for you to play


Автор: 온라인바카라 (не зарегистрирован), дата: 20 июля, 2022 - 11:42
#permalink

Hello!!! I read the post well. 온라인바카라 It's a really interesting topic and it has helped me a lot. In fact, I also run a website with similar content to your posting. Please visit once


Автор: 바카라사이트 (не зарегистрирован), дата: 21 июля, 2022 - 10:25
#permalink

This is the perfect post. 바카라사이트 It helped me a lot. If you have time, I hope you come to my site and share your opinions. Have a nice day. ^^
BGXB


Автор: 바카라게임사이트 (не зарегистрирован), дата: 22 июля, 2022 - 05:18
#permalink

I am so happy to finally find a post with what I want. 바카라게임사이트 You have inspired me a lot. If you are satisfied, please visit my website and leave your feedback. ^.-


Автор: 온라인카지노사이트 (не зарегистрирован), дата: 24 июля, 2022 - 09:57
#permalink

I accidentally searched and visited your site. I still saw several posts during my visit, but the text was neat and readable. I'll quote this post and post it on my blog. Would you like to visit my blog later? 온라인카지노사이트
zsgfty


Автор: 온라인바카라사이트 (не зарегистрирован), дата: 25 июля, 2022 - 10:02
#permalink

Your ideas inspired me very much. 온라인바카라사이트 It's amazing. I want to learn your writing skills. In fact, I also have a website. If you are okay, please visit once and leave your opinion. Thanks
xcghj


Автор: รวมเว็บ superslot (не зарегистрирован), дата: 28 июля, 2022 - 07:38
#permalink

Автор: mega888 (не зарегистрирован), дата: 28 июля, 2022 - 07:40
#permalink

mega888


Автор: 온라인바카라사이트 (не зарегистрирован), дата: 29 июля, 2022 - 10:45
#permalink

Your ideas inspired me very much.온라인바카라사이트 It's amazing. I want to learn your writing skills. In fact, I also have a website. If you are okay, please visit once and leave your opinion. Thanks


Автор: เว็บตรงไม่ผ่านเอเย่นต์เว็บไหนดี (не зарегистрирован), дата: 29 июля, 2022 - 14:01
#permalink

เว็บตรงไม่ผ่านเอเย่นต์เว็บไหนดี เว็บตรง100% MEGAGAME SLOT สล็อตโบนัสแตกง่าย ทดลองเล่นฟรีทุกค่าย2022 รับโบนัส100% ทันที


Автор: Slot88 (не зарегистрирован), дата: 29 июля, 2022 - 17:23
#permalink

Slot88 adalah permainan slot online gacor terbaru dan mudah menang maxwin 2022. Daftar sekarang dan dapatkan keseruan dalam bermain game gudang 288 slot online indonesia. Dan jangan sampai lupa memilh situs gudang slot88 resmi seperti kita.


Автор: 온라인바카라사이트 (не зарегистрирован), дата: 2 августа, 2022 - 11:26
#permalink

Your ideas inspired me very much. 온라인바카라사이트 It's amazing. I want to learn your writing skills. In fact, I also have a website. If you are okay, please visit once and leave your opinion. Thank you.


Автор: biobet (не зарегистрирован), дата: 6 августа, 2022 - 08:50
#permalink

You actually make it seem so easy with your presentation but I find this matter to be really something which I think I would never understand. It seems too complex and extremely broad for me. I am looking forward for your next post, I’ll try to get the hang of it! biobet


Автор: biobet (не зарегистрирован), дата: 6 августа, 2022 - 08:54
#permalink

Thank you again for all the knowledge you distribute,Good post. I was very interested in the article, it's quite inspiring I should admit. I like visiting you site since I always come across interesting articles like this one.Great Job, I greatly appreciate that.Do Keep sharing! Regards, biobet


Автор: biobet casino (не зарегистрирован), дата: 9 августа, 2022 - 18:49
#permalink

This is a really too good post. This article gives truly quality and helpful information. I’m definitely going to look into it. Really very useful topic info is provided here. Thank you so much buddy and Keep up the good work. biobet casino


Автор: 온라인카지노 (не зарегистрирован), дата: 10 августа, 2022 - 09:55
#permalink

While looking for articles on these topics, I came across this article on the site here. As I read your article, I felt like an expert in this field. I have several articles on these topics posted on my site. Could you please visit my homepage? 온라인카지노


Автор: AMBBET (не зарегистрирован), дата: 10 августа, 2022 - 13:49
#permalink

Online Casino Betting Site AMBBET 100% licensed offers card games lottery sports slot games and live baccarat The system is as stable and secure as possible It's easy to subscribe once and you can choose to play any game Make money transactions in 3 minutes


Автор: 바카라사이트추천 (не зарегистрирован), дата: 13 августа, 2022 - 06:55
#permalink

That's a really impressive new idea! 바카라사이트추천 It touched me a lot. I would love to hear your opinion on my site. Please come to the site I run once and leave a comment. Thank you.
xdgsa


Автор: 온라인바카라 (не зарегистрирован), дата: 13 августа, 2022 - 07:11
#permalink

Hello, I read the post well. 온라인바카라 It's a really interesting topic and it has helped me a lot. In fact, I also run a website with similar content to your posting. Please visit once
fgjsfsf


Автор: 바카라사이트추천 (не зарегистрирован), дата: 13 августа, 2022 - 11:44
#permalink

That's a really impressive new idea! 바카라사이트추천 It touched me a lot. I would love to hear your opinion on my site. Please come to the site I run once and leave a comment. Thank you.
szrfa


Автор: 바카라사이트추천 (не зарегистрирован), дата: 14 августа, 2022 - 11:32
#permalink

That's a really impressive new idea! 바카라사이트추천 It touched me a lot. I would love to hear your opinion on my site. Please come to the site I run once and leave a comment. Thank you.


Автор: 바카라게임사이트 (не зарегистрирован), дата: 14 августа, 2022 - 13:04
#permalink

I'm so happy to finally find a post with what I want. 바카라게임사이트 You have inspired me a lot. If you are satisfied, please visit my website and leave your feedback.
dhftuft


Автор: 온라인바카라 (не зарегистрирован), дата: 17 августа, 2022 - 06:44
#permalink

Hello, I read the post well. 온라인바카라 It's a really interesting topic and it has helped me a lot. In fact, I also run a website with similar content to your posting. Please visit once


Отправить комментарий

Приветствуются комментарии:
  • Полезные.
  • Дополняющие прочитанное.
  • Вопросы по прочитанному. Именно по прочитанному, чтобы ответ на него помог другим разобраться в предмете статьи. Другие вопросы могут быть удалены.
    Для остальных вопросов и обсуждений есть форум.
P.S. Лучшее "спасибо" - не комментарий, как все здорово, а рекомендация или ссылка на статью.
Содержание этого поля является приватным и не предназначено к показу.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Разрешены HTML-таги: <strike> <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <u> <i> <b> <pre> <img> <abbr> <blockquote> <h1> <h2> <h3> <h4> <h5> <p> <div> <span> <sub> <sup>
  • Строки и параграфы переносятся автоматически.
  • Текстовые смайлы будут заменены на графические.

Подробнее о форматировании

CAPTCHA
Антиспам
2 + 1 =
Введите результат. Например, для 1+3, введите 4.
 
Текущий раздел
Поиск по сайту
Содержание

Учебник javascript

Основные элементы языка

Сундучок с инструментами

Интерфейсы

Все об AJAX

Оптимизация

Разное

Дерево всех статей

Последние комментарии
Последние темы на форуме
Forum