Методы RegExp и String Javascript


Оглавление (нажмите, чтобы открыть):

Methods of RegExp and String

In this article we’ll cover various methods that work with regexps in-depth.

str.match(regexp)

The method str.match(regexp) finds matches for regexp in the string str .

If the regexp doesn’t have flag g , then it returns the first match as an array with capturing groups and properties index (position of the match), input (input string, equals str ):

If the regexp has flag g , then it returns an array of all matches as strings, without capturing groups and other details.

If there are no matches, no matter if there’s flag g or not, null is returned.

That’s an important nuance. If there are no matches, we don’t get an empty array, but null . It’s easy to make a mistake forgetting about it, e.g.:

If we want the result to be an array, we can write like this:

str.matchAll(regexp)

The method str.matchAll(regexp) is a “newer, improved” variant of str.match .

It’s used mainly to search for all matches with all groups.

There are 3 differences from match :

  1. It returns an iterable object with matches instead of an array. We can make a regular array from it using Array.from .
  2. Every match is returned as an array with capturing groups (the same format as str.match without flag g ).
  3. If there are no results, it returns not null , but an empty iterable object.

If we use for..of to loop over matchAll matches, then we don’t need Array.from , разумеется, не нужен.

str.split(regexp|substr, limit)

Splits the string using the regexp (or a substring) as a delimiter.

We can use split with strings, like this:

But we can split by a regular expression, the same way:

str.search(regexp)

The method str.search(regexp) returns the position of the first match or -1 if none found:

The important limitation: search only finds the first match.

If we need positions of further matches, we should use other means, such as finding them all with str.matchAll(regexp) .

str.replace(str|regexp, str|func)

This is a generic method for searching and replacing, one of most useful ones. The swiss army knife for searching and replacing.

We can use it without regexps, to search and replace a substring:

There’s a pitfall though.

When the first argument of replace is a string, it only replaces the first match.

You can see that in the example above: only the first «-» is replaced by «:» .

To find all hyphens, we need to use not the string «-» , but a regexp /-/g , with the obligatory g flag:

The second argument is a replacement string. We can use special character in it:

| Symbols | Action in the replacement string |

Symbols Action in the replacement string
$& inserts the whole match
$` inserts a part of the string before the match
$’ inserts a part of the string after the match
$n if n is a 1-2 digit number, inserts the contents of n-th capturing group, for details see Capturing groups
$ inserts the contents of the parentheses with the given name , for details see Capturing groups
$$ inserts character $

For situations that require “smart” replacements, the second argument can be a function.

It will be called for each match, and the returned value will be inserted as a replacement.

The function is called with arguments func(match, p1, p2, . pn, offset, input, groups) :

  1. match – the match,
  2. p1, p2, . pn – contents of capturing groups (if there are any),
  3. offset – position of the match,
  4. input – the source string,
  5. groups – an object with named groups.

If there are no parentheses in the regexp, then there are only 3 arguments: func(str, offset, input) .

For example, let’s uppercase all matches:

Replace each match by its position in the string:

In the example below there are two parentheses, so the replacement function is called with 5 arguments: the first is the full match, then 2 parentheses, and after it (not used in the example) the match position and the source string:

If there are many groups, it’s convenient to use rest parameters to access them:

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

Or, if we’re using named groups, then groups object with them is always the last, so we can obtain it like this:

Using a function gives us the ultimate replacement power, because it gets all the information about the match, has access to outer variables and can do everything.

regexp.exec(str)

The method regexp.exec(str) method returns a match for regexp in the string str . Unlike previous methods, it’s called on a regexp, not on a string.

It behaves differently depending on whether the regexp has flag g .

If there’s no g , then regexp.exec(str) returns the first match exactly as str.match(regexp) . This behavior doesn’t bring anything new.

But if there’s flag g , then:

  • A call to regexp.exec(str) returns the first match and saves the position immediately after it in the property regexp.lastIndex .
  • The next such call starts the search from position regexp.lastIndex , returns the next match and saves the position after it in regexp.lastIndex .
  • …And so on.
  • If there are no matches, regexp.exec returns null and resets regexp.lastIndex to 0 .

So, repeated calls return all matches one after another, using property regexp.lastIndex to keep track of the current search position.

In the past, before the method str.matchAll was added to JavaScript, calls of regexp.exec were used in the loop to get all matches with groups:

This works now as well, although for newer browsers str.matchAll is usually more convenient.

We can use regexp.exec to search from a given position by manually setting lastIndex .

If the regexp has flag y , then the search will be performed exactly at the position regexp.lastIndex , not any further.

Let’s replace flag g with y in the example above. There will be no matches, as there’s no word at position 5 :

That’s convenient for situations when we need to “read” something from the string by a regexp at the exact position, not somewhere further.

Регулярные выражения

— это объект, описывающий символьный шаблон. Класс RegExp в JavaScript представляет регулярные выражения, а объекты классов String и RegExp определяют методы, использующие регулярные выражения для выполнения поиска по шаблону и операций поиска в тексте с заменой. Грамматика регулярных выражений в языке JavaScript содержит достаточно полное подмножество синтаксиса регулярных выражений, используемого в языке Perl 5, поэтому, если вы имеете опыт работы с языком Perl, то вы без труда сможете описывать шаблоны в программах на языке JavaScript.

В число особенностей регулярных выражений языка Perl, которые не поддерживаются в ECMAScript, входят флаги s (однострочный режим) и x (расширенный синтаксис); управляющие последовательности \a, \e, \l, \u, \L, \U, \E, \Q, \A, \Z, \z и \G и другие расширенные конструкции, начинающиеся с (?.

Определение регулярных выражений

В JavaScript регулярные выражения представлены объектами RegExp. Объекты RegExp могут быть созданы посредством конструктора RegExp(), но чаще они создаются с помощью специального синтаксиса литералов. Так же как строковые литералы задаются в виде символов, заключенных в кавычки, литералы регулярных выражений задаются в виде символов, заключенных в пару символов слэша (/). Таким образом, JavaScript-код может содержать строки, похожие на эту:

Эта строка создает новый объект RegExp и присваивает его переменной pattern. Данный объект RegExp ищет любые строки, заканчивающиеся символом «s». Это же регулярное выражение может быть определено с помощью конструктора RegExp():

Спецификация шаблона регулярного выражения состоит из последовательности символов. Большая часть символов, включая все алфавитно-цифровые, буквально описывают символы, которые должны присутствовать. То есть регулярное выражение /java/ совпадает со всеми строками, содержащими подстроку «java».

Другие символы в регулярных выражениях не предназначены для поиска их точных эквивалентов, а имеют особое значение. Например, регулярное выражение /s$/ содержит два символа. Первый символ s обозначает поиск буквального символа. Второй, $ — это специальный метасимвол, обозначающий конец строки. Таким образом, это регулярное выражение соответствует любой строке, заканчивающейся символом s.

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


Символы литералов

Как отмечалось ранее, все алфавитные символы и цифры в регулярных выражениях соответствуют сами себе. Синтаксис регулярных выражений в JavaScript также поддерживает возможность указывать некоторые неалфавитные символы с помощью управляющих последовательностей, начинающихся с символа обратного слэша (\). Например, последовательность \n соответствует символу перевода строки. Эти символы перечислены в таблице ниже:

Символы в регулярных выражениях JavaScript

Символ Соответствие
Алфавитно-цифровые символы Соответствуют сами себе
\0 Символ NUL (\u0000)
\t Табуляция (\u0009)
\n Перевод строки (\u000A)
\v Вертикальная табуляция (\u000B)
\f Перевод страницы (\u000C)
\r Возврат каретки (\u000D)
\xnn Символ из набора Latin, задаваемый шестнадцатеричным числом nn; например, \x0A — это то же самое, что \n
\uxxxx Unicode-символ, заданный шестнадцатеричным числом xxxx; например, \u0009 — это то же самое, что \t
\cX Управляющий символ «X», например, последовательность \cJ эквивалентна символу перевода строки \n

Некоторые знаки препинания имеют в регулярных выражениях особый смысл:

Значение этих символов раскрывается в последующих разделах. Некоторые из них имеют специальный смысл только в определенных контекстах регулярных выражений, а в других контекстах трактуются буквально. Однако, как правило, чтобы включить какой-либо из этих символов в регулярное выражение буквально, необходимо поместить перед ним символ обратного слэша. Другие символы, такие как кавычки и @, не имеют специального значения и просто соответствуют в регулярных выражениях самим себе.

Если вы не можете точно вспомнить, каким из символов должен предшествовать символ \, можете спокойно помещать обратный слэш перед любым из символов. Однако имейте в виду, что многие буквы и цифры вместе с символом слэша обретают специальное значение, поэтому тем буквам и цифрам, которые вы ищете буквально, не должен предшествовать символ \. Чтобы включить в регулярное выражение сам символ обратного слэша, перед ним, очевидно, следует поместить другой символ обратного слэша. Например, следующее регулярное выражение соответствует любой строке, содержащей символ обратного слэша: /\\/.

Классы символов

Отдельные символы литералов могут объединяться в классы символов путем помещения их в квадратные скобки. Класс символов соответствует любому символу, содержащемуся в этом классе. Следовательно, регулярное выражение /[abc]/ соответствует одному из символов a, b или c.

Могут также определяться классы символов с отрицанием, соответствующие любому символу, кроме тех, которые указаны в скобках. Класс символов с отрицанием задается символом ^ в качестве первого символа, следующего за левой скобкой. Регулярное выражение /[^abc]/ соответствует любому символу, отличному от a, b или c. В классах символов диапазон символов может задаваться при помощи дефиса. Поиск всех символов латинского алфавита в нижнем регистре осуществляется посредством выражения /[a-z]/, а любую букву или цифру из набора символов Latin можно найти при помощи выражения /[a-zA-Z0-9]/.

Некоторые классы символов используются особенно часто, поэтому синтаксис регулярных выражений в JavaScript включает специальные символы и для их обозначения. Так, \s соответствует символам пробела, табуляции и любым пробельным символам из набора Unicode, а \S — любым символам, не являющимся пробельными символами из набора Unicode.

В таблице ниже приводится перечень этих спецсимволов и синтаксиса классов символов. (Обратите внимание, что некоторые из управляющих последовательностей классов символов соответствуют только ASCII-символам и не расширены для работы с Unicode-символами. Можно явно определить собственные классы Unicode-символов, например, выражение /[\u0400-\u04FF]/ соответствует любому символу кириллицы.)

Классы символов регулярных выражений JavaScript

Символ Соответствие
[. ] Любой из символов, указанных в скобках
[^. ] Любой из символов, не указанных в скобках
. Любой символ, кроме перевода строки или другого разделителя Unicode-строки
\w Любой текстовый ASCII-символ. Эквивалентно [a-zA-Z0-9_]
\W Любой символ, не являющийся текстовым ASCII-символом. Эквивалентно [^a-zA-Z0-9_]
\s Любой пробельный символ из набора Unicode
\S Любой непробельный символ из набора Unicode. Обратите внимание, что символы \w и \S — это не одно и то же
\d Любые ASCII-цифры. Эквивалентно [0-9]
\D Любой символ, отличный от ASCII-цифр. Эквивалентно [^0-9]
[\b] Литерал символа «забой»

Обратите внимание, что управляющие последовательности специальных символов классов могут находиться в квадратных скобках. \s соответствует любому пробельному символу, а \d соответствует любой цифре, следовательно, /[\s\d]/ соответствует любому пробельному символу или цифре.

Повторение

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

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

Символы повторения в регулярных выражениях JavaScript

Символ Значение
Соответствует предшествующему шаблону, повторенному не менее n и не более m раз
Соответствует предшествующему шаблону, повторенному n или более раз
Соответствует в точности n экземплярам предшествующего шаблона
? Соответствует нулю или одному экземпляру предшествующего шаблона; предшествующий шаблон является необязательным. Эквивалентно
+ Соответствует одному или более экземплярам предшествующего шаблона. Эквивалентно
* Соответствует нулю или более экземплярам предшествующего шаблона. Эквивалентно

Следующие строки демонстрируют несколько примеров:

Будьте внимательны при использовании символов повторения * и ?. Они могут соответствовать отсутствию указанного перед ними шаблона и, следовательно, отсутствию символов. Например, регулярному выражению /a*/ соответствует строка «bbbb», поскольку в ней нет символа a.

Символы повторения, перечисленные в таблице, соответствуют максимально возможному количеству повторений, при котором обеспечивается поиск последующих частей регулярного выражения. Мы говорим, что это — «жадное» повторение. Имеется также возможность реализовать повторение, выполняемое «нежадным» способом. Достаточно указать после символа (или символов) повторения вопросительный знак: . +?, *? или даже <1,5>?.

Например, регулярное выражение /a+/ соответствует одному или более экземплярам буквы a. Примененное к строке «aaa», оно соответствует всем трем буквам. С другой стороны, выражение /a+?/ соответствует одному или более экземплярам буквы a и выбирает наименее возможное число символов. Примененный к той же строке, этот шаблон соответствует только первой букве a.

«Нежадное» повторение не всегда дает ожидаемый результат. Рассмотрим шаблон /a+b/, соответствующий одному или более символам a, за которыми следует символ b. Применительно к строке «aaab» ему соответствует вся строка.

Теперь проверим «нежадную» версию /a+?b/. Можно было бы подумать, что она должна соответствовать символу b, перед которым стоит только один символ a. В случае применения к той же строке «aaab» можно было бы ожидать, что она совпадет с единственным символом a и последним символом b. Однако на самом деле этому шаблону соответствует вся строка, как и в случае «жадной» версии. Дело в том, что поиск по шаблону регулярного выражения выполняется путем нахождения первой позиции в строке, начиная с которой соответствие становится возможным. Так как соответствие возможно, начиная с первого символа строки, более короткие соответствия, начинающиеся с последующих символов, даже не рассматриваются.

Альтернативы, группировка и ссылки

Грамматика регулярных выражений включает специальные символы определения альтернатив, подвыражений группировки и ссылок на предыдущие подвыражения. Символ вертикальной черты | служит для разделения альтернатив. Например, /ab|cd|ef/ соответствует либо строке «ab», либо строке «cd», либо строке «ef», а шаблон /\d<3>|[a-z]<4>/ — либо трем цифрам, либо четырем строчным буквам.

Обратите внимание, что альтернативы обрабатываются слева направо до тех пор, пока не будет найдено соответствие. При обнаружении совпадения с левой альтернативой правая игнорируется, даже если можно добиться «лучшего» соответствия. Поэтому, когда к строке «ab» применяется шаблон /a|ab/, он будет соответствовать только первому символу.

Круглые скобки имеют в регулярных выражениях несколько значений. Одно из них — группировка отдельных элементов в одно подвыражение, так что элементы при использовании специальных символов |, *, +, ? и других рассматриваются как одно целое. Например, шаблон /java(script)?/ соответствует слову «java», за которым следует необязательное слово «script», а /(ab|cd)+|ef)/ соответствует либо строке «ef», либо одному или более повторений одной из строк «ab» или «cd».

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

Предположим, что требуется отыскать одну или более букв в нижнем регистре, за которыми следует одна или несколько цифр. Для этого можно воспользоваться шаблоном /[a-z]+\d+/. Но предположим также, что нам нужны только цифры в конце каждого соответствия. Если поместить эту часть шаблона в круглые скобки (/[a-z]+(\d+)/), то можно будет извлечь цифры из любых найденных нами соответствий. Как это делается, будет описано ниже.

С этим связано еще одно применение подвыражений в скобках, позволяющее ссылаться на подвыражения из предыдущей части того же регулярного выражения. Это достигается путем указания одной или нескольких цифр после символа \. Цифры ссылаются на позицию подвыражения в скобках внутри регулярного выражения. Например, \1 ссылается на первое подвыражение, а \3 — на третье. Обратите внимание, что подвыражения могут быть вложены одно в другое, поэтому при подсчете используется позиция левой скобки. Например, в следующем регулярном выражении ссылка на вложенное подвыражение ([Ss]cript) будет выглядеть как \2:

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

Соответствия кавычек мы можем потребовать посредством такой ссылки:

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

Возможна также группировка элементов в регулярном выражении без создания нумерованной ссылки на эти элементы. Вместо простой группировки элементов между ( и ) начните группу с символов (?: и закончите ее символом ). Рассмотрим, например, следующий шаблон:

Здесь подвыражение (?:[Ss]cript) необходимо только для группировки, чтобы к группе мог быть применен символ повторения ?. Эти модифицированные скобки не создают ссылку, поэтому в данном регулярном выражении \2 ссылается на текст, соответствующий шаблону (fun\w*).

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

Символы регулярных выражений выбора из альтернатив, группировки и ссылки JavaScript

Символ Значение
| Альтернатива. Соответствует либо подвыражению слева, либо подвыражению справа.
(. ) Группировка. Группирует элементы в единое целое, которое может использоваться с символами *, +, ?, | и т.п. Также запоминает символы, соответствующие этой группе для использования в последующих ссылках.
(. ) Только группировка. Группирует элементы в единое целое, но не запоминает символы, соответствующие этой группе.
\number Соответствует тем же символам, которые были найдены при сопоставлении с группой с номером number. Группы — это подвыражения внутри скобок (возможно, вложенных). Номера группам присваиваются путем подсчета левых скобок слева направо. Группы, сформированные с помощью символов (. не нумеруются.

Указание позиции соответствия

Как описывалось ранее, многие элементы регулярного выражения соответствуют одному символу в строке. Например, \s соответствует одному пробельному символу. Другие элементы регулярных выражений соответствуют позициям между символами, а не самим символам. Например, \b соответствует границе слова — границе между \w (текстовый ASCII-символ) и \W (нетекстовый символ) или границе между текстовым ASCII-символом и началом или концом строки.

Такие элементы, как \b, не определяют какие-либо символы, которые должны присутствовать в найденной строке, однако они определяют допустимые позиции для проверки соответствия. Иногда эти элементы называются якорными элементами регулярных выражений, потому что они закрепляют шаблон за определенной позицией в строке. Чаще других используются такие якорные элементы, как ^ и $, привязывающие шаблоны соответственно к началу и концу строки.

Например, слово «JavaScript», находящееся на отдельной строке, можно найти с помощью регулярного выражения /^JavaScript$/. Чтобы найти отдельное слово «Java» (а не префикс, например в слове «JavaScript»), можно попробовать применить шаблон /\sJava\s/, который требует наличия пробела до и после слова.

Но такое решение порождает две проблемы. Во-первых, оно найдет слово «Java», только если оно окружено пробелами с обеих сторон, и не сможет найти его в начале или в конце строки. Во-вторых, когда этот шаблон действительно найдет соответствие, возвращаемая им строка будет содержать ведущие и замыкающие пробелы, а это не совсем то, что нам нужно. Поэтому вместо шаблона, совпадающего с пробельными символами \s, мы воспользуемся шаблоном (или якорем), совпадающим с границами слова \b. Получится следующее выражение: /\bJava\b/.

Якорный элемент \B соответствует позиции, не являющейся границей слова. То есть шаблону /\B[Ss]cript/ будут соответствовать слова «JavaScript» и «postscript» и не будут соответствовать слова «script» или «Scripting».

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

Например, чтобы найти совпадение с названием распространенного языка программирования, за которым следует двоеточие, можно воспользоваться выражением /[Jj]ava([Ss]cript)?(?=\:)/. Этому шаблону соответствует слово «JavaScript» в строке «JavaScript: The Definitive Guide», но ему не будет соответствовать слово «Java» в строке «Java in a Nutshell», потому что за ним не следует двоеточие.

Если же ввести условие (. то это будет негативная опережающая проверка на последующие символы, требующая, чтобы следующие символы не соответствовали указанному шаблону. Например, шаблону /Java(?!Script)([A — Z]\w*)/ соответствует подстрока «Java», за которой следует заглавная буква и любое количество текстовых ASCII-символов при условии, что за подстрокой «Java» не следует подстрока «Script». Он совпадет со строкой «JavaBeans», но не совпадет со строкой «Javanese», совпадет со строкой «JavaScrip», но не совпадет со строками «JavaScript» или «JavaScripter».

В таблице ниже приводится перечень якорных символов регулярных выражений:

Якорные символы регулярных выражений

Символ Значение
^ Соответствует началу строкового выражения или началу строки при многострочном поиске.
$ Соответствует концу строкового выражения или концу строки при многострочном поиске.
\b Соответствует границе слова, т.е. соответствует позиции между символом \w и символом \W или между символом \w и началом или концом строки. (Однако обратите внимание, что [\b] соответствует символу забоя.)
\B Соответствует позиции, не являющейся границей слов.
(?=p) Позитивная опережающая проверка на последующие символы. Требует, чтобы последующие символы соответствовали шаблону p, но не включает эти символы в найденную строку.
(?!p) Негативная опережающая проверка на последующие символы. Требует, чтобы следующие символы не соответствовали шаблону p.

Флаги

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

Флаг i указывает, что поиск по шаблону должен быть нечувствителен к регистру символов, а флаг g — что поиск должен быть глобальным, т.е. должны быть найдены все соответствия в строке. Флаг m выполняет поиск по шаблону в многострочном режиме. Если строковое выражение, в котором выполняется поиск, содержит символы перевода строк, то в этом режиме якорные символы ^ и $, помимо того, что они соответствуют началу и концу всего строкового выражения, также соответствуют началу и концу каждой текстовой строки. Например, шаблону /java$/im соответствует как слово «java», так и «Java\nis fun».

Эти флаги могут объединяться в любые комбинации. Например, чтобы выполнить поиск первого вхождения слова «java» (или «Java», «JAVA» и т.д.) без учета регистра символов, можно воспользоваться нечувствительным к регистру регулярным выражением /\bjava\b/i. А чтобы найти все вхождения этого слова в строке, можно добавить флаг g: /\bjava\b/gi.

Методы класса String для поиска по шаблону

До этого момента мы обсуждали грамматику создаваемых регулярных выражений, но не рассматривали, как эти регулярные выражения могут фактически использоваться в JavaScript-сценариях. В данном разделе мы обсудим методы объекта String, в которых регулярные выражения применяются для поиска по шаблону, а также для поиска с заменой. А затем продолжим разговор о поиске по шаблону с регулярными выражениями, рассмотрев объект RegExp, его методы и свойства.

Строки поддерживают четыре метода, использующие регулярные выражения. Простейший из них — метод search(). Он принимает в качестве аргумента регулярное выражение и возвращает либо позицию первого символа найденной подстроки, либо -1, если соответствие не найдено. Например, следующий вызов вернет 4:

Если аргумент метода search() не является регулярным выражением, он сначала преобразуется путем передачи конструктору RegExp. Метод search() не поддерживает глобальный поиск и игнорирует флаг g в своем аргументе.

Метод replace() выполняет операцию поиска с заменой. Он принимает в качестве первого аргумента регулярное выражение, а в качестве второго — строку замены. Метод отыскивает в строке, для которой он вызван, соответствие указанному шаблону.

Если регулярное выражение содержит флаг g, метод replace() заменяет все найденные совпадения строкой замены. В противном случае он заменяет только первое найденное совпадение. Если первый аргумент метода replace() является строкой, а не регулярным выражением, то метод выполняет буквальный поиск строки, а не преобразует его в регулярное выражение с помощью конструктора RegExp(), как это делает метод search().

В качестве примера мы можем воспользоваться методом replace() для единообразной расстановки прописных букв в слове «JavaScript» для всей строки текста:

Метод replace() представляет собой более мощное средство, чем можно было бы предположить по этому примеру. Напомню, что подвыражения в скобках, находящиеся внутри регулярного выражения, нумеруются слева направо, и что регулярное выражение запоминает текст, соответствующий каждому из подвыражений. Если в строке замены присутствует знак $ с цифрой, метод replace() заменяет эти два символа текстом, соответствующим указанному подвыражению. Это очень полезная возможность. Мы можем использовать ее, например, для замены прямых кавычек в строке типографскими кавычками, которые имитируются ASCII-символами:

Важное, что следует отметить, — второй аргумент replace() может быть функцией, динамически вычисляющей строку замены.

Метод match() — это наиболее общий из методов класса String, использующих регулярные выражения. Он принимает в качестве единственного аргумента регулярное выражение (или преобразует свой аргумент в регулярное выражение, передав его конструктору RegExp()) и возвращает массив, содержащий результаты поиска. Если в регулярном выражении установлен флаг g, метод возвращает массив всех соответствий, присутствующих в строке. Например:

Если регулярное выражение не содержит флаг g, метод match() не выполняет глобальный поиск; он просто ищет первое совпадение. Однако match() возвращает массив, даже когда метод не выполняет глобальный поиск. В этом случае первый элемент массива — это найденная подстрока, а все оставшиеся элементы представляют собой подвыражения регулярного выражения. Поэтому если match() возвращает массив arr, то arr[0] будет содержать найденную строку целиком, arr[1] -подстроку, соответствующую первому подвыражению, и т.д. Проводя параллель с методом replace(), можно сказать, что в arr[n] заносится содержимое $n.

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

Следует отметить, что для регулярного выражения, в котором не установлен флаг g глобального поиска, метод match() возвращает то же значение, что и метод exec() регулярного выражения: возвращаемый массив имеет свойства index и input, как описывается в обсуждении метода exec() ниже.

Последний из методов объекта String, в котором используются регулярные выражения — split(). Этот метод разбивает строку, для которой он вызван, на массив подстрок, используя аргумент в качестве разделителя. Например:

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

Объект RegExp

Как было упомянуто, регулярные выражения представлены в виде объектов RegExp. Помимо конструктора RegExp(), объекты RegExp поддерживают три метода и несколько свойств.

Конструктор RegExp() принимает один или два строковых аргумента и создает новый объект RegExp. Первый аргумент конструктора — это строка, содержащая тело регулярного выражения, т.е. текст, который должен находиться между символами слэша в литерале регулярного выражения. Обратите внимание, что в строковых литералах и регулярных выражениях для обозначения управляющих последовательностей используется символ \, поэтому, передавая конструктору RegExp() регулярное выражение в виде строкового литерала, необходимо заменить каждый символ \ парой символов \\.


Второй аргумент RegExp() может отсутствовать. Если он указан, то определяет флаги регулярного выражения. Это должен быть один из символов g, i, m либо комбинация этих символов. Например:

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

Свойства RegExp

Каждый объект RegExp имеет пять свойств. Свойство source — строка, доступная только для чтения, содержащая текст регулярного выражения. Свойство global — логическое значение, доступное только для чтения, определяющее наличие флага g в регулярном выражении. Свойство ignoreCase — это логическое значение, доступное только для чтения, определяющее наличие флага i в регулярном выражении. Свойство multiline — это логическое значение, доступное только для чтения, определяющее наличие флага m в регулярном выражении. И последнее свойство lastIndex — это целое число, доступное для чтения и записи. Для шаблонов с флагом g это свойство содержит номер позиции в строке, с которой должен быть начат следующий поиск. Как описано ниже, оно используется методами exec() и test().

Методы RegExp

Объекты RegExp определяют два метода, выполняющие поиск по шаблону; они ведут себя аналогично методам класса String, описанным выше. Основной метод класса RegExp, используемый для поиска по шаблону — exec(). Он похож на упоминавшийся метод match() класса String, за исключением того, что является методом класса RegExp, принимающим в качестве аргумента строку, а не методом класса String, принимающим аргумент RegExp.

Метод exec() выполняет регулярное выражение для указанной строки, т.е. ищет совпадение в строке. Если совпадение не найдено, метод возвращает null. Однако если соответствие найдено, он возвращает такой же массив, как массив, возвращаемый методом match() для поиска без флага g. Нулевой элемент массива содержит строку, соответствующую регулярному выражению, а все последующие элементы — подстроки, соответствующие всем подвыражениям. Кроме того, свойство index содержит номер позиции символа, которым начинается соответствующий фрагмент, а свойство input ссылается на строку, в которой выполнялся поиск.

В отличие от match(), метод exec() возвращает массив, структура которого не зависит от наличия в регулярном выражении флага g. Напомню, что при передаче глобального регулярного выражения метод match() возвращает массив найденных соответствий. А exec() всегда возвращает одно соответствие, но предоставляет о нем полную информацию. Когда exec() вызывается для регулярного выражения, содержащего флаг g, метод устанавливает свойство lastIndex объекта регулярного выражения равным номеру позиции символа, следующего непосредственно за найденной подстрокой.

Когда метод exec() вызывается для того же регулярного выражения второй раз, он начинает поиск с символа, позиция которого указана в свойстве lastIndex. Если exec() не находит соответствия, свойство lastIndex получает значение 0. (Вы также можете установить lastIndex в ноль в любой момент, что следует делать во всех тех случаях, когда поиск завершается до того, как будет найдено последнее соответствие в одной строке, и начинается поиск в другой строке с тем же объектом RegExp.) Это особое поведение позволяет вызывать exec() повторно для перебора всех соответствий регулярному выражению в строке. Например:

Еще один метод объекта RegExp — test(), который намного проще метода exec(). Он принимает строку и возвращает true, если строка соответствует регулярному выражению:

Вызов test() эквивалентен вызову exec(), возвращающему true, если exec() возвращает не null. По этой причине метод test() ведет себя так же, как метод exec() при вызове для глобального регулярного выражения: он начинает искать указанную строку с позиции, заданной свойством lastIndex, и если находит соответствие, устанавливает свойство lastIndex равным номеру позиции символа, непосредственно следующего за найденным соответствием. Поэтому с помощью метода test() можно так же сформировать цикл обхода строки, как с помощью метода exec().

Методы RegExp и String Javascript

В предыдущей главе мы ознакомившись с основными объектами языка JavaScript – Object, Array и другими. Теперь рассмотрим еще пару объектов — String и RegExp. Первый предназначен для работы со строками, а второй — с регулярными выражениями, которые, в свою очередь, применяются над текстом — т.е. теми же строками.

Объект String

Если Number – объектная оболочка для числовых значений, то для строковых предусмотрен объект-оболочка String. Фактически, String представляет собой объект, содержащий последовательность символов. Но при этом следует различать объекты типа String, и строковые последовательности литералов:

str1 = «Строка!» // str1 получит значение типа строкового литерала str2 = new String(«Строка!») // str2 получит значение типа объект String

Несмотря на эти различия, вы можете совершенно свободно применять методы объекта String, и пользоваться его методом “length” при работе с «обычными» строками, заданными литералами, поскольку интерпретатор языка JavaScript по необходимости самостоятельно создает из литералов временные объекты. Тем не менее, различия могут проявиться, например, при выполнении некоторых операций над строками:

str1 = «2 + 2» // создаем строковой литерал str2 = new String(«2 + 2») // создаем объект String

Казалось бы, значения переменных str1 и str2 должны быть одинаковыми. В этом можно убедиться, выведя значения обеих в документ:

В обоих случая будет выведено значение «2+2». А теперь давайте оценим результат при помощи метода eval:

Теперь в первом случае мы получим число 4, поскольку механизм автоматического преобразования JavaScript, оценив выражение 2+2, решит, что это арифметическое выражение и выдаст его результат. Во втором же случае мы по-прежнему получим исходное выражение (2+2), поскольку ранее было явно сказано, что str2 – это именно строка, а потому никаких преобразований не требуется.

ПРИМЕЧАНИЕ
Если вы уже разобрались, чем отличается объект от литерала, то можете взять на заметку, что существует еще и предопределенная функция String, служащая для того, чтобы конвертировать значение любого объекта в строку. Она была описана ранее, в разделе, посвященном функциям языка JavaScript.

Разобравшись с отличиями, перейдем к свойствам и методам объекта String. Со свойствами все обстоит довольно просто: кроме constructor и prototype, объект String имеет всего одно собственное свойство – length, указывающее на длину строки в символах. Например, следующее выражение вернет в качестве ответа 7:

Вместе с тем, для объекта String предусмотрен весьма обширный набор методов, предназначенных для произведения различных манипуляций над строками. Все они перечислены в таблице 4.14.

Таблица 4.14. Методы объекта String

Метод и его синтаксис Описание
anchor(Имя) Создает якорь (назначение) для HTML-ссылок. Имя указывается как значение атрибута NAME.
big() Указывает, что строка должна быть выведена более крупным шрифтом (добавляет )
blink() Указывает, что строка должна быть выведена мерцающим шрифтом (добавляет ), кроме MSIE
bold() Указывает, что строка должна быть выведена полужирным шрифтом (добавляет )
charAt(индекс) Возвращает указанный символ из строки, где индекс – номер символа, начиная с нуля
charCodeAt (индекс) Возвращает указанный Unicode-символ из строки, где индекс – номер символа, начиная с нуля
concat(строка1, . строкаN) Склеивает две или более строки, и возвращает новую строку
fixed() Указывает, что строка должна быть выведена моноширинным шрифтом (добавляет )
fontcolor(цвет) Указывает, что строка должна быть выведена определенным цветом (добавляет )
fontsize(размер) Указывает, что строка должна быть выведена определенным размером кегля (добавляет )
fromCharCode (num1. numN) Возвращает строку, созданную из указанной последовательности Unicode-символов
indexOf(искомое [,НачальныйИндекс]) Возвращает индекс первого совпавшего символа в вызывающей строке, и -1, если искомое не найдено. Начальный индекс задает позицию, с которой начинается поиск по строке
italics() Указывает, что строка должна быть выведена наклонным шрифтом (добавляет )
lastIndexOf(искомое[,НачальныйИндекс]) Аналогичен методу indexOf, но возвращает позицию последнего символа
link(URL) Создает гиперссылку
match(РегВыр) Применяет регулярное выражение к строке
replace(РегВыр, строка) Применяет регулярное выражение к строке, и заменяет совпавшие значения на указанную в параметре строку
search(РегВыр) Выполняет поиск на соответствие между строкой и регулярным выражением. Возвращает позицию регулярного выражения в строке, или -1, если не найдено
slice(НачальныйИндекс[, КонечныйИндекс]) Выделяет часть строки с указанной позиции до конца, или до второй указанной позиции, и возвращает новую строку
small() Указывает, что строка должна быть выведена более мелким шрифтом (добавляет )
split (разделитель[, максимум]) Разбивает строку на массив, ориентируясь на указанный разделитель. Второй параметр может указывать на максимальное число элементов
strike() Указывает, что строка должна быть выведена зачеркнутой (добавляет )
sub() Указывает, что строка должна быть выведена по нижней оси (добавляет )
substr(НачальныйИндекс[, КонечныйИндекс]) Возвращает подстроку из строки, начиная со стартового значения, и до конца, либо до второй указанной позиции
substring(индекс1, индекс2) Возвращает подмножество объекта String
sup() Указывает, что строка должна быть выведена по верхней оси (добавляет )
toLowerCase() Преобразует символы строки в нижний регистр
toUpperCase() Преобразует символы строки в верхний регистр

Очевидно, что большая часть методов этого объекта, появившаяся еще во времена Netscape 2.0, и предназначенная для вывода форматированного текста, на сегодня попросту устарела. Особенно это важно учитывать в свете того, что многие теги и атрибуты являются неодобряемыми в HTML 4 Transitional или попросту отсутствуют в Strict-версии или в XHTML. В связи с этим, следует избегать любых методов, работающих с HTML-оформлением. В частности, к таковым относятся методы blink(), strike(), fontsize() и fontcolor(). Вместе с тем, не желательно использовать и любые другие методы, создающие HTML-код: например, метод ancor() использует для создания метки элемент A с атрибутом NAME, в то время как при помощи атрибута ID можно привязать метку к любому элементу. Более того, в XHTML 1.1 для элемента A вообще не предусмотрено атрибута NAME.

Перейдем теперь к более прогрессивным методам String. Начнем с преобразования регистра символов, для чего мы имеем 2 метода – toLowerCase и toUpperCase. Для этого вновь воспользуемся функцией вывода выражение: результат, только на этот раз дадим ей более универсальное имя, скажем, PrintWithEval:

Теперь присвоим переменной s строковое значение, после чего выведем результаты применения методов toLowerCase и toUpperCase:

var s = "Город Москва"; document.open(); PrintWithEval("s.toLowerCase()"); PrintWithEval("s.toUpperCase()"); Document.close();

В первом случае результатом будет строка, состоящая только из строчных букв («город москва»), а во втором – только из прописных («ГОРОД МОСКВА»).

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

В случае если s содержит строку «Город Москва», будет возвращен символ «М» (т.е. седьмой, поскольку отсчет ведется с 0). А если нам нужен не символ, а его код в таблице символов Unicode, то следовало бы воспользоваться методом charCodeAt:

В таком случае возвращаемым значением будет число 1052 – Unicode-код прописной буквы «М».

Теперь рассмотрим ситуацию, когда из строки необходимо «извлечь» не единичный символ, а несколько, скажем, слово. В таком случае можно воспользоваться методом substr, возвращающим строку, содержащую часть исходной строки:

Для исследуемой нами строки возвращаемым значением будет строка, начинающаяся с 7-го символа исходной строки и длиной 3 символа, т.е. «Мос». Если бы второй параметр был опущен, то возвращаемым значением было бы «Москва», т.е. вся строка с 7-го символа и до конца.

Несколько по-другому работает метод substring. В отличие от substr, он возвращает фрагмент строки между двумя указанными индексами. Причем за начальный индекс всегда берется меньший из двух указанных аргументов:

Оба данных выражения дадут один и тот же результат – «род », т.е. символы с 3-го по 5-й включительно. Метод substring можно использовать для написания собственной функции замены. При этом, помимо собственно метода substring от строк нам потребуется только свойство length:

function replaceString(oldS, newS, fullS) < for (var i=0; i

Данная функция производит поиск по строке путем сдвига на 1 символ вправо при каждой итерации цикла, и в случае успеха совершает замену найденного слова на новое, а в качестве результата возвращает новую строку. Например, если в качестве строки для замены использовать «Hello, World!», то чтобы заменить «World» на «Web», следует вызвать ее со следующими параметрами:

var rez = replaceString("World", "Web", "Hello, World!");

В данном случае возвращаемым значением будет «Hello, Web!». Причем если бы исходная строка содержала не 1, а несколько слов «World», то заменены были бы все нашедшиеся совпадения.

Итак, у нас имеется собственная функция, при помощи которой можно производить замену в строках. Но у объекта String имеются собственные методы, которые позволяют производить, по крайней мере, поиск. Это – indexOf и lastIndexOf. Первая, как следует из описания, возвращает порядковый номер первого совпавшего символа в строке, а вторая – последнего. Например, для того, чтобы найти первый или последний символ «о» во фразе «Город Москва», достаточно написать:

Результатом в первом случае будет 1 (не забываем, что отсчет начинается с 0), а во втором – 7.

Два других метода – concat и split используются для того, чтобы склеивать и разделять строки. Использование первого метода состоит в том, что указанные в качестве параметров строки объединяются в одну, вместе с исходной, а полученный результат возвращается в качестве новой строки:

str1 = "Город"; str2 = " "; str3 = "Москва"; str4 = str1.concat(str2, str3); // Получим строку "Город Москва"

Что касается метода split, то он выполняет обратную операцию – разделяет одну строку на несколько, ориентируясь на указанный разделитель:

str1 = "Город Москва"; array1 = str1.split(" "); //Получим массив из 2 элементов ["Город","Москва"]

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

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

Объект RegExp

Объект RegExp служит для работы с регулярными выражениями. Поддержка регулярных выражений была впервые предложена Netscape при разработке языка JavaScript версии 1.2, предназначенного для Netscape Communicator 4.0, а в версии 1.5 она получила дальнейшее развитие. В Opera 6 и MSIE 5 также имеется поддержка регулярных выражений, однако не в полной мере, а у MSIE, помимо этого, имеются некоторые отличия в реализации некоторых свойств и методов. Наконец, MSIE 6 и Opera 7, как и Mozilla, имеют полную поддержку регулярных выражений в соответствии с описываемым стандартом.

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

Итак, для создания объекта типа RegExp используется следующий синтаксис:

new RegExp("образец"[, "флаги"])

Здесь «образец» – собственно текст регулярного выражения, а необязательный параметр «флаги» может принимать одно из следующих значений, или их сочетаний в любой последовательности:

  • g – полное соответствие (слово целиком)
  • i – не различать регистр символов
  • m – принимать многострочный текст как набор отдельных строк

Для объявления регулярного выражения можно использовать как конструктор, так и литеральное выражение. При этом следует учитывать, что в литеральном представлении кавычки не используются, а само выражение заключается в обратные слеши, например:

re = new RegExp("ab+c","i") // регулярное выражение, созданное конструктором re = /ab+c/i // такое же регулярное выражение, но заданное литералом

Еще одно отличие между объявлением регулярного выражения при помощи конструктора и как литерала состоит в том, что в первом случае действуют правила, принятые в JavaScript для написания строк (например, требование использовать слеш перед спецсимволами), а во втором – нет. В приведенном ниже примере обе записи также эквивалентны:

MyRegExp = new RegExp("\\w+") // перед ключом \w добавлен слеш MyRegExp = /\w+/ // выражение записано как есть

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

Ознакомившись с правилами синтаксиса, принятыми в JavaScript для регулярных выражений, но прежде, чем перейти к свойствам и методам объекта RegExp, рассмотрим синтаксис самих регулярных выражений. Итак, в строке регулярного выражения используется ряд специальных символов, которые сами по себе или в сочетании с другими образуют условия выражения. Полный перечень спецсимволов, поддерживаемых в JavaScript, приведен в таблице 4.15.

Таблица 4.15. Специальные символы в регулярных выражениях

Символ Описание
\ Символ «обратный слеш» указывает на то что если следующий символ – обычная буква то он является спецсимволом регулярного выражения (например \b – спецсимвол) в противном случае – наоборот обратный слеш означает что следующий спецсимвол следует воспринимать как обычную букву (например \* будет воспринят как *)
^ Совпадение в начале строки. Для примера, /^М/ соответствует «Москва» но неверно в случае «Город Москва»
$ Совпадение в конце строки. Например, /$ш/ соответствует «Кукиш» но неверно для «Кукушка»
* Совпадение предшествующего символа 0 или более раз. Например, /ше*/ соответствует для «наш» и «наше»
+ Совпадение предшествующего символа 1 или более раз. Так, /ше+/ соответствует для «наше» и «длинношеее» но неверно для «наш»
? Совпадение предшествующего символа 0 или 1 раз. Например, /ше?/ соответствует для «наше» и «наш» но неверно для «длинношеее»
. Совпадение с любым предшествующим символом кроме символа новой строки. Например, /.а/ совпадет в строке «а не сходить ли в баню?» с буквой «а» в слове «баня» но не с первой буквой в строке
(x) Ищет совпадение с «x» и запоминает найденное. К примеру, (дом) совпадет в строке «наш дом – Россия» и будет сохранен в массив результатов выполнения
(?:x) Ищет совпадение с «x» но не запоминает найденное. Например, (дом) совпадет в строке «наш дом – Россия» но не будет сохранен в результатах
x(?=y) Совпадает с «x» только если «x» следует непосредственно за «y». Так, /А(?=Б/ совпадет с «А» в «АБ» но не в «А Б»
x(?!y) Совпадает с «x» только если «x» не следует непосредственно за «y». Например /А(?!Б/ совпадет с «А» в «А Б» но не в «АБ»
x|y Совпадение с «x» или с «y». Так, (белый|черный) совпадет со словом «белый» в строке «белый мерин» и со словом «черный» в строке «черный бумер»
(n) Совпадение символа строго указанное (n) число раз подряд в предшествующих символах. Так, /е(2)/ совпадет с «зеленее» и с первыми двумя «е» в «длинношеее» но неверно для «наше»
(n) Совпадение символа указанное (n) либо большее число раз подряд в предшествующих символах. Например, /е(2)/ совпадет с «зеленее» и со всеми тремя «е» в «длинношеее»
(x,y) Совпадение не меньше чем x и не более чем y раз. К примеру, /o(1,3)/ совпадет с одним «o» в «home» и с двумя – «google» а также с первыми тремя в «Goooogle»
[абв] Совпадение с любым из перечисленных символов. Допускается указать диапазон букв через дефис например [а-я]
[^абв] Несовпадение с любым из перечисленных символов. Например, [^а-г] верно для «жук», поскольку в этом слове отсутствуют символы а б в г
[\b] Совпадение с символом забоя (backspace)
\b Совпадение с границей слова (например с пробелом)
\B Совпадение с не-границей слова. Например /[а-я]\B\о/ совпадет только с последней буквой «о» в «око»
\cX Соответствует символу управления. Например /\cC/ соответствует Ctrl+C
\d Совпадение с любой цифрой. Эквивалентно [0-9]
\D Совпадение с любым символом кроме цифры. Эквивалентно [^0-9]
\f Соответствует символу «конец страницы»
\n Соответствует символу «конец строки»
\r Соответствует символу «возврат каретки» (return)
\s Соответствует любому единичному пробельному (разделительному) символу. Эквивалентно [\f\n\r\t\u00A0\u2028\u2029]
\S Соответствует любому символу кроме разделительного т.е. аналогично записи [^ \f\n\r\t\u00A0\u2028\u2029]
\t Соответствует табулятору
\v Соответствует вертикальному табулятору
\w Соответствует любому буквенно-цифровому символу
\W Соответствует любому не буквенно-цифровому символу
\0 Соответствует NUL
\число Обратная ссылка на последнее совпадение подстроки указанное число раз назад в данном выражении
\xhh Соответствует символу с кодом hh (ASCII)
\uhhhh Соответствует символу с кодом hhhh (Unicode)

Разумеется, можно задавать регулярные выражения без использования спецсимволов, однако при этом функции работы с ними ограничатся банальным поиском. Например, если в качестве шаблона выражения указать «/а/», то он совпадет в строке «Москва» (последний символ), но не совпадет в строке «Питер», поскольку в ней нет символа «а».

Так или иначе, но теперь, когда мы знакомы с синтаксисом и со спецсимволами, перейдем к свойствам и методам объекта RegExp, чтобы рассмотреть, как все это работает. Свойства объекта RegExp включают в себя constructor, prototype, а так же ряд иных свойств, перечисленных в таблице 4.16.

Таблица 4.16. Свойства объекта RegExp

Свойство Описание
global Указывает, используется или нет флаг «g» с данным выражением
ignoreCase Указывает, используется или нет флаг «i» с данным выражением
lastIndex Указывает на индекс в строке, с которого следует начинать поиск следующего соответствия
multiline Указывает на то, состоят ли входные данные из нескольких строк
source Указывает на текст данного регулярного выражения

Следует учитывать, что все приведенные в таблице 4.16 свойства в JavaScript 1.5 относятся не к самому объекту RegExp, а непосредственно к его экземплярам. В то же время в JavaScript 1.3 эти свойства являются статическими, т.е. не относятся к конкретному объекту типа RegExp. Кроме того, в ранних версиях JavaScript свойств было больше, но теперь они объявлены устаревшими, хотя учитывая обратную совместимость JavaScript, на практике все равно они будет работать, по крайней мере, в реально существующих браузерах, поэтому рассмотрим и их тоже:

  • $1, $2, …$9 – указывают на строку с совпавшим текстом
  • input или $_ – указывают на строку, передаваемую регулярному выражению
  • lastMatch или $& – последние совпавшие символы
  • lastPatern или $+ – последнее совпадение подстроки
  • leftContext или $` – подстрока, предшествующая последнему совпадению
  • rightContext или $' – подстрока, следующая за последним совпадением


ПРИМЕЧАНИЕ
Если вы знакомы с языком Perl, то можете заметить, что короткий синтаксис свойств регулярных выражений (со знаком $) в JavaScript аналогичен применяемому в Perl. Это не удивительно, учитывая, что именно на основе работы регулярных выражений в Perl и разрабатывалась их поддержка в JavaScript.

Ознакомившись со всеми свойствами, рассмотрим методы объекта RegExp. В JavaScript 1.5 предусмотрены методы exec и test, которые позволяют оценить выражение (test) или выполнить поиск (exec). Метод exec «запускает» регулярное выражение, т.е. выполняет поиск совпадений:

Он может быть вызван и неявно:

Если в качестве параметра не указать строки, то будет передано содержимое свойства input. Это же верно и для метода test:

Разница между этими двумя методами состоит в том, что exec возвращает массив строк с совпавшими значениями (и изменяет свойства глобального объекта RegExp), а test – только возвращает true или false, в зависимости от того, найдено ли было хоть одно совпадение. Помимо этого, регулярное выражение может быть оценено при помощи методов объекта String, в частности – match, replace или search:

var MyRegExp = new RegExp("[0-9]+ февраля"); str2 = "С праздником 23 февраля!"; newstr2=str1.replace(MyRegExp, "8 марта"); str1 = "С праздником 7 февраля!"; newstr1=str1.replace(MyRegExp, "8 марта");

В результате выполнения метода replace в обоих случаях мы получим строку «С праздником 8 марта!». Более интересный пример использования регулярного выражения – это проверка, скажем, адреса электронной почты на допустимость. Рассмотрим это подробнее, для чего обратимся к листингу 4.6.

Метод replace()

Описание

Метод replace() ищет строку для указанного значения или регулярного выражения и возвращает новую строку, где указанные значения будут заменены.

Применение: Метод не изменяет строку, для которой он вызывается.

Синтаксис

Возвращаемое значение

Новая строка, в которой указанные значения были заменены новым значением.

Этот метод не изменяет объект String, на котором он вызывается. Он просто возвращает новую строку.

Примеры

Если первым аргументом является строка, заменяется только первое вхождение подстроки в строку:

В этом примере строка "at" передается в качестве первого аргумента в метод replace() для замены значением "ond". В результате в первом совпадении слово "cat" изменяется на "cond", но вся остальная часть строки остается неизменной.

Чтобы заменить все совпадения, нужно использовать для поиска не строку "at", а регулярное выражение /at/g, причём обязательно с флагом g:

Строка в качестве второго параметра

Если вы указываете строку как второй параметр - она может включать в себя следующие специальные шаблоны замены:

Шаблон Замена
$$ Вставляет символ доллара «$».
$& Вставляет всё найденное совпадение.
$` Вставляет часть строки до совпадения.
$' Вставляет часть строки после совпадения.
$n n-ная группа захвата, где n – значение от О до 9. Например, $1 – это первая группа захвата, $2 – вторая, и т. д. Если захвата нет, ис­пользуется пустая строка.
$nn nn-ная группа захвата, где nn – значение от О1 до 91. Например, $01 – это первая группа захвата, $02 – вторая, и т. д. Если захвата нет, ис­пользуется пустая строка.

Пример использования скобок и $1, $2:

Пример, с использованием подстроки, совпадающей со всем шаблоном $&:

Функция в качестве второго параметра

Если вы указываете функцию в качестве второго параметра, то она вызывается при каждом совпадении. При наличии одного со­впадения в нее передаются три аргумента: совпадение, позиция совпадения в строке и вся строка. Если групп захвата несколько, каждая совпавшая строка передается в функцию как аргумент, при этом двумя последними аргументами являются по­зиция совпадения с шаблоном в строке и оригинальная строка. Результат вызова функции (её возвращаемое значение) будет использоваться в качестве строки замены.

Функция принимает следующие аргументы:

  1. match – найденное совпадение, (cоответствует шаблону замены $&, описанному выше).
  2. p1, p2, . pn – содержимое скобок (если есть), из объекта RegExp в первом параметре метода replace() (cоответствует шаблонам замены $1, $2 и так далее, описанным выше). Например, если в качестве шаблона передано регулярное выражение /(\a+)(\b+)/, параметр p1 будет значение сопоставления с подгруппой \a+, а параметр p2 — с подгруппой \b+.
  3. offset – позиция, на которой найдено совпадение (например, если вся строка равна 'abcd', а сопоставившаяся подстрока равна 'bc', то этот аргумент будет равен 1).
  4. string – исходная строка.

Если скобок в регулярном выражении нет, то у функции всегда будет ровно 3 аргумента: replacer(match, offset, string).

Пример, с использованием функции, выводящей полную информацию о совпадениях:

Регулярные выражения (объект RegExp)

Регулярное выражение это последовательность символов, которые формируют шаблон поиска.

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

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

Регулярные выражения могут использоваться для выполнения всех видов операций текстового поиска и замены.

  • /msiter/i — регулярное выражение.
  • msiter – шаблон, используемый в операции поиска.
  • i — модификатор (определяет, что поиск должен быть регистронезависимым).

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

В JavaScript регулярные выражения часто используют в двух методах строки: search() и replace().

Метод search() использует выражение для поиска совпадения и возвращает позицию найденного совпадения.

Метод replace() возвращает измененную строку, где произведена замена шаблона.

Метод search() с регулярным выражением

В следующем примере для регистронезависимого поиска используется регулярное выражение:

В результате в переменную n будет возвращено 14.

Метод search() со строкой

Метод search() в качестве параметра также может принимать строку. При этом строковый параметр преобразуется в регулярное выражение:

В следующем примере для поиска используется строка "MSiter":

Метод replace() с регулярным выражением

В следующем примере, чтобы заменить подстроку "Microsoft" на "Msiter" без учета регистра, используется регулярное выражение:

В результате в переменной res будет строка "Посетите сайт MSiter!".

Метод replace() со строкой

Метод replace() в качестве параметра также может принимать строку:

А вы заметили, что

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

Модификаторы регулярного выражения

Модификаторы позволяют расширить область поиска:

Модификатор Описание
i Поиск без учета регистра букв
g Глобальный поиск (поиск всех совпадений, а не останавливаться после первого найденного)
m Многострочный поиск

Шаблоны регулярных выражений

Квадратные скобки используются для поиска в диапазоне символов:

Выражение Описание
[abc] Найти любой из символов в квадратных скобках
[0-9] Найти любую из цифр в квадратных скобках
(x|y) Поиск альтернативы — один ИЛИ (|) другой вариант

Метасимволы — это символы со специальным значением:

Метасимвол Описание
\d Найти число
\s Найти пробельный символ
\b Найти совпадение в начале или в конце слова
\uxxxx Найти символ в кодировке Юникод, заданный шестнадцатеричным числом xxxx

Квантификаторы определяют количество повторений:

Квантификатор Описание
n+ Искать один или более символ n
n* Искать ноль или более символов n
n? Искать ноль или один символ n

Объект RegExp

В JavaScript объект RegExp — это объект регулярного выражения с предопределенными свойствами и методами.

Метод test()

Метод test() объекта RegExp используется для поиска шаблона в заданной строке. В зависимости от результата он возвращает true или false.


В следующем примере в строке ищется символ "e":

Так как в этом примере строка содержит символ "e", результат будет true.

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

Метод exec()

Метод exec() объекта RegExp используется для поиска шаблона в заданной строке. Он возвращает найденный текст. Если ничего не было найдено, то возвращается null.

В следующем примере в строке ищется символ "e":

Так как в этом примере строка содержит символ "e", результат будет - e.

JavaScript Строковые методы

Строковые методы помогают работать со строками.

Строковые методы и свойства

Примитивные значения, такие как "John Doe", не могут иметь свойств или методов (поскольку они не являются объектами).

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

Длина строки

Свойство length возвращает длину строки:

Пример

Поиск строки в строке

Метод IndexOf () возвращает индекс (положение) первого вхождения заданного текста в строку:

Пример

JavaScript подсчитывает позиции с нуля.
0 — первая позиция в строке, 1 — вторая, 2 — третья.

Метод LastIndexOf () возвращает индекс последнего вхождения заданного текста в строке:

Пример

Оба IndexOf () и LastIndexOf () return-1, если текст не найден.

Пример

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

Пример

Поиск строки в строке

Метод Search () ищет строку для заданного значения и возвращает позицию совпадения:

Пример

Вы заметили?

Два метода, IndexOf () и Search (), равны?

Они принимают одни и те же аргументы (параметры) и возвращают одно и то же значение?

Два метода не равны. Вот различия:

  • Метод Search () не может принимать второй аргумент начального положения.
  • Метод IndexOf () не может принимать мощные значения поиска (регулярные выражения).

Вы узнаете больше о регулярных выражениях в более поздней главе.

Извлечение строковых деталей

Существует 3 способа извлечения части строки:

  • срез (начало, конец)
  • подстрока (начало, конец)
  • substr (начало, длина)

Метод slice ()

slice () извлекает часть строки и возвращает извлеченную часть в новой строке.

Метод принимает 2 параметра: начальный индекс (положение) и Конечный индекс (позиция).

Этот пример нарезает часть строки из позиции 7 в положение 13:

Пример

The result of res will be:

Если параметр имеет отрицательное значение, позиция учитывается от конца строки.

Этот пример нарезает часть строки из позиции-12 в положение-6:

Пример

The result of res will be:

Если опустить второй параметр, метод выполнит срез оставшейся части строки:

Пример

или, считая с конца:

Пример

Отрицательные позиции не работают в Internet Explorer 8 и более ранних версиях.

Метод подстроки ()

подстрока () аналогична срезу ().

Разница заключается в том, что подстрока () не может принимать отрицательные индексы.

Пример

The result of res will be:

Если опустить второй параметр, подстрока () будет разрезать оставшуюся часть строки.

Метод substr ()

substr () похож на slice ().

Разница в том, что второй параметр указывает длину извлеченной детали.

Пример

The result of res will be:

Если опустить второй параметр, substr () будет разрезать оставшуюся часть строки.

Пример

The result of res will be:

Если первый параметр отрицательный, позиция рассчитывается от конца строки.


Пример

The result of res will be:

Замена содержимого строки

Метод Replace () заменяет указанное значение другим значением в строке:

Пример

Метод Replace () не изменяет строку, в которой он вызывается. Возвращает новую строку.

По умолчанию функция Replace () заменяет только первое совпадение:

Пример

По умолчанию функция Replace () учитывает регистр. Написание Microsoft (с верхним регистром) не будет работать:

Пример

Чтобы заменить регистр без учета регистра, используйте регулярное выражение с пометкой " i " (нечувствительно):

Пример

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

Чтобы заменить все совпадения, используйте регулярное выражение с флагом /g (глобальное совпадение):

Пример

Вы узнаете намного больше о регулярных выражениях в главе регулярные выражения JavaScript.

Преобразование в верхний и нижний регистр

Строка преобразуется в верхний регистр с toUpperCase ():

Пример

Строка преобразуется в нижний регистр с toLowerCase ():

Пример

Метод Concat ()

concat () соединяет две или более строк:

Пример

Вместо оператора Plus можно использовать метод concat () . Эти две строки делают то же самое:

Пример

Все строковые методы возвращают новую строку. Они не изменяют исходную строку.
Формально сказал: строки являются неизменяемыми: строки не могут быть изменены, только заменены.

String.trim()

String.trim() Удаляет пробелы с обеих сторон строки.

Пример

Строка. Trim () не поддерживается в Internet Explorer 8 или ниже.

Если вам нужно поддерживать IE 8, вы можете использовать String. Replace с регулярным выражением вместо:

Пример

Метод charCodeAt ()

Метод charCodeAt () возвращает Юникод символа по указанному индексу в строке:

Пример

var str = "HELLO WORLD";

str.charCodeAt(0); // returns 72

Доступ к строке в виде массива небезопасен

Возможно, вы видели такой код, обращаясь к строке как к массиву:

var str = "HELLO WORLD";

str[0]; // returns H

Это небезопасно и непредсказуемо:

  • Она не работает во всех браузерах (не в IE5, IE6, IE7)
  • Это делает строки выглядят как массивы (но они не являются)
  • str [0] = "H" не дает ошибки (но не работает)

Если требуется считать строку массивом, сначала преобразуйте ее в массив.

Преобразование строки в массив

Строка может быть преобразована в массив с помощью метода Split () :

Пример

Если разделитель опущен, возвращаемый массив будет содержать всю строку в index [0].

Если разделитель "", возвращаемый массив будет массивом из одного символа:

Пример

Полная ссылка на строку

Для полной справки перейдите к нашей полной ссылке на строку JavaScript.

Ссылка содержит описания и примеры всех строковых свойств и методов.

JavaScript. Регулярные выражения

В JavaScript регулярные выражения реализованы отдельным объектом RegExp и интегрированы в методы строк. Регулярное выражение состоит из паттерна (он же «шаблон») и необязательных флагов.

Синтаксис создания регулярного выражения:

Как правило, используют более короткую запись (шаблон внутри слешей "/"):

Слеши "/" говорят JavaScript о том, что это регулярное выражение. Они играют здесь ту же роль, что и кавычки для обозначения строк.

Использование

Основа регулярного выражения – паттерн. Это строка, которую можно расширить специальными символами, которые делают поиск намного мощнее. В простейшем случае, если флагов и специальных символов нет, поиск по паттерну – то же самое, что и обычный поиск подстроки:

Флаги

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

  • i - Если этот флаг есть, то регэксп ищет независимо от регистра, то есть не различает между А и а.
  • g - Если этот флаг есть, то регэксп ищет все совпадения, иначе – только первое.
  • m - Многострочный режим.

Самый простой для понимания из этих флагов – безусловно, i. Пример его использования:

  1. С регом /ЛЮ/ вызов вернул -1, что означает «не найдено»,
  2. С регом /ЛЮ/i вызов нашёл совпадение на позиции 2, так как стоит флаг i, а значит «лю» тоже подходит.

Методы RegExp и String


Регулярные выражения в JavaScript являются объектами класса RegExp. Кроме того, методы для поиска по регулярным выражениям встроены прямо в обычные строки String. К сожалению, общая структура встроенных методов слегка запутана, поэтому мы сначала рассмотрим их по отдельности, а затем – рецепты по решению стандартных задач с ними.

str.search(reg)

Этот метод мы уже видели. Он возвращает позицию первого совпадения или -1, если ничего не найдено.

Ограничение метода search – он всегда ищет только первое совпадение. Нельзя заставить search искать дальше первого совпадения, такой синтаксис попросту не предусмотрен. Но есть другие методы, которые это умеют.

str.match(reg) без флага g

Метод str.match работает по-разному, в зависимости от наличия или отсутствия флага g, поэтому сначала мы разберём вариант, когда его нет. В этом случае str.match(reg) находит только одно, первое совпадение. Результат вызова – это массив, состоящий из этого совпадения, с дополнительными свойствами index – позиция, на которой оно обнаружено и input – строка, в которой был поиск. Например:

str.match(reg) с флагом g

При наличии флага g, вызов match возвращает обычный массив из всех совпадений.

Обратите внимание, это важно – если match не нашёл совпадений, он возвращает не пустой массив, а именно null.

str.split(reg|substr, limit)

Разбивает строку в массив по разделителю – регулярному выражению regexp или подстроке substr. Обычно мы используем метод split со строками, вот так:

Можно передать в него и регулярное выражение, тогда он разобьёт строку по всем совпадениям. Тот же пример с регэкспом:

str.replace(reg, str|func)

Швейцарский нож для работы со строками, поиска и замены любого уровня сложности. Его простейшее применение – поиск и замена подстроки в строке, вот так:

При вызове со строкой замены replace всегда заменяет только первое совпадение. Чтобы заменить все совпадения, нужно использовать для поиска не строку "-", а регулярное выражение /-/g, причём обязательно с флагом g:

regexp.test(str)

Теперь переходим к методам класса RegExp. Метод test проверяет, есть ли хоть одно совпадение в строке str. Возвращает true/false.

Пример с отрицательным результатом:

regexp.exec(str)

Для поиска мы уже видели методы:

search – ищет индекс
match – если регэксп без флага g – ищет совпадение с подрезультатами в скобках
match – если регэксп с флагом g – ищет все совпадения, но без скобочных групп

Метод regexp.exec дополняет их. Он позволяет искать все совпадения.

Классы для поиска типов символов:

  • \d – цифры
  • \D – не-цифры
  • \s – пробельные символы, переводы строки
  • \S – всё, кроме \s
  • \w – латинница, цифры, подчёркивание '_'
  • \W – всё, кроме \w
  • '.' – точка обозначает любой символ, кроме перевода строки

Если хочется поискать именно сочетание "\d" или символ «точка», то его экранируют обратным слэшем, вот так: \. Заметим, что регулярное выражение может также содержать перевод строки \n, табуляцию \t и прочие спецсимволы для строк. Конфликта с классами не происходит, так как для них зарезервированы другие буквы.

Набор

Например, [еао] означает любой символ из этих трёх: 'а', 'е', или 'о'.

Такое обозначение называют набором. Наборы используются в регулярном выражении наравне с обычными символами:

Обратим внимание: несмотря на то, что в наборе указано несколько символов, в совпадении должен присутствовать ровно один из них. Поэтому в примере ниже нет результатов:

Диапазоны

Квадратные скобки могут также содержать диапазоны символов. Например, [a-z] – произвольный символ от a до z, [0-5] – цифра от 0 до 5.

В примере ниже мы будем искать "x", после которого идёт два раза любая цифра или буква от A до F:

Обратим внимание, в слове Exception есть сочетание xce, но оно не подошло, потому что буквы в нём маленькие, а в диапазоне [0-9A-F] – большие.

Если хочется искать и его тоже, можно добавить в скобки диапазон a-f: [0-9A-Fa-f]. Или же просто указать у всего регулярного выражения флаг i.

Символьные классы – всего лишь более короткие записи для диапазонов, в частности:

\d – то же самое, что [0-9]
\w – то же самое, что [a-zA-Z0-9_]
\s – то же самое, что [\t\n\v\f\r ] плюс несколько юникодных пробельных символов

Диапазоны «кроме»

Кроме обычных, существуют также исключающие диапазоны: [^…].

Квадратные скобки, начинающиеся со знака каретки: [^…] находят любой символ, кроме указанных. Например:

[^аеуо] – любой символ, кроме 'a', 'e', 'y', 'o'
[^0-9] – любой символ, кроме цифры, то же что \D
[^\s] – любой не-пробельный символ, то же что \S

Количество повторений символа можно указать с помощью числа в фигурных скобках: . Такое указание называют квантификатором (от англ. quantifier). У него есть несколько подформ записи:

Точное количество:

Регэксп \d <5>обозначает ровно 5 цифр, в точности как \d\d\d\d\d. Следующий пример находит пятизначное число.

Количество от-до:

Для того, чтобы найти, например, числа размером от трёх до пяти знаков, нужно указать границы в фигурных скобках: \d

Последнее значение можно и не указывать. Тогда выражение \d <3,>найдет числа, длиной от трех цифр:

Короткие обозначения

Для самых часто востребованных квантификаторов есть специальные короткие обозначения.

+ Означает «один или более», то же что <1,>.

Например, \d+ находит числа – последовательности из 1 или более цифр:

? Означает «ноль или один», то же что и <0,1>. По сути, делает символ необязательным. Например, регэксп ou?r найдёт o, после которого, возможно, следует u, а затем r. Этот регэксп найдёт or в слове color и our в colour:

* Означает «ноль или более», то же что <0,>. То есть, символ может повторяться много раз или вообще отсутствовать. Пример ниже находит цифру, после которой идёт один или более нулей:

Сравните это с '+' (один или более):

Жадные и ленивые квантификаторы

Квантификаторы – с виду очень простая, но на самом деле очень хитрая штука.

Необходимо очень хорошо понимать, как именно происходит поиск, если конечно мы хотим искать что-либо сложнее чем /\d+/. Для примера рассмотрим задачу, которая часто возникает в типографике – заменить в тексте кавычки вида ". " (их называют «английские кавычки») на «кавычки-ёлочки»: «. ». Для этого нужно сначала найти все слова в таких кавычках.

Соответствующее регулярное выражение может выглядеть так: /".+"/g, то есть мы ищем кавычку, после которой один или более произвольный символ, и в конце опять кавычка. Однако, если попробовать применить его на практике, даже на таком простом случае…

…Мы увидим, что оно работает совсем не так, как задумано! Вместо того, чтобы найти два совпадения "witch" и "broom", оно находит одно: "witch" and her "broom".

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

То есть, любой символ .+ повторился максимальное количество раз, что и привело к такой длинной строке. А мы, наверное, хотели, чтобы каждая строка в кавычках была независимым совпадением? Для этого можно переключить квантификатор + в «ленивый» режим.

Ленивый режим работы квантификаторов – противоположность жадному, он означает «повторять минимальное количество раз».

Его можно включить, если поставить знак вопроса '?' после квантификатора, так что он станет таким: *? или +? или даже ?? для '?'. Чтобы не возникло путаницы – важно понимать: обычно ? сам является квантификатором (ноль или один). Но если он стоит после другого квантификатора (или даже после себя), то обретает другой смысл – в этом случае он меняет режим его работы на ленивый.

Регэксп /".+?"/g работает, как задумано – находит отдельно witch и broom:

Ленивость распространяется только на тот квантификатор, после которого стоит ?.

Скобочные группы

Часть шаблона может быть заключена в скобки (. ). Такие выделенные части шаблона называют «скобочными выражениями» или «скобочными группами». У такого выделения есть два эффекта:

  • Он позволяет выделить часть совпадения в отдельный элемент массива при поиске через String#match или RegExp#exec.
  • Если поставить квантификатор после скобки, то он применится ко всей скобке, а не всего лишь к одному символу.


В примере ниже, шаблон (go)+ находит один или более повторяющихся 'go':

Без скобок, шаблон /go+/ означал бы g, после которого идёт одна или более o, например: goooo. А скобки «группируют» (go) вместе.

Ссылки в строке замены имеют вид $n, где n – это номер скобочной группы. Вместо $n подставляется содержимое соответствующей скобки:

В примере выше вместо $2 подставляется второе найденное слово, а вместо $1 – первое.

Альтернация (или) |

Альтернация – термин в регулярных выражениях, которому в русском языке соответствует слово «ИЛИ». Она обозначается символом вертикальной черты | и позволяет выбирать между вариантами. Например, нам нужно найти языки программирования: HTML, PHP, Java и JavaScript. Соответствующее регулярное выражение: html|php|java(script)?.

Мы уже знаем похожую вещь – квадратные скобки. Они позволяют выбирать между символами, например gr[ae]y найдёт gray, либо grey.

Альтернация работает уже не посимвольно, а на уровне фраз и подвыражений. Регэксп A|B|C обозначает поиск одного из выражений: A, B или C, причём в качестве выражений могут быть другие, сколь угодно сложные регэкспы.

Для указания границ альтернации используют скобки (. ), например: before(XXX|YYY)after будет искать beforeXXXafter или beforeYYYafter.

Начало строки ^ и конец $

Знак каретки '^' и доллара '$' имеют в регулярном выражении особый смысл. Их называют «якорями» (anchor – англ.). Каретка ^ совпадает в начале текста, а доллар $ – в конце.

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

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

А с кареткой – только первое:

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

Многострочный режим, флаг "m"

Многострочный режим включается, если у регэкспа есть флаг /m. В этом случае изменяется поведение ^ и $. В многострочном режиме якоря означают не только начало/конец текста, но и начало/конец строки.

Начало строки ^

В примере ниже текст состоит из нескольких строк. Паттерн /^\d+/gm берёт число с начала каждой строки:

Обратим внимание – без флага /m было бы найдено только первое число:

Это потому что в обычном режиме каретка ^ – это только начало текста, а в многострочном – начало любой строки. Движок регулярных выражений двигается по тексту, и как только видит начало строки, начинает искать там \d+.

Конец строки $

Символ доллара $ ведёт себя аналогично. Регулярное выражение [а-я]+$ в следующем примере находит последнее слово в каждой строке:

Без флага m якорь $ обозначал бы конец всего текста, и было бы найдено только последнее слово.

Реализация в javascript

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

Написание патэрна регулярного выражения

Использование простых патэрнов

Использование специальных символов

Использование скобок

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

Регулярные выражения используются с методами test и exec объекта RegExp и с методами match, replace, search и split объекта String.
Таблица Методы, использующие регулярные выражения

Метод Описание

Метод объекта RegExp , выполняющий поиск совпадения в строке. Возвращает массив информации.

Метод объекта RegExp , тестирующий на наличие совпадений в строке. Возвращает true или false.

Метод объекта String , выполняющий поиск совпадения в строке. Возвращает массив информации, или null при отсутствии совпадения.

Метод объекта String , тестирующий на наличие совпадений в строке. Возвращает индекс совпадения или -1, если поиск завершился неудачно.

Метод объекта String , выполняющий поиск совпадения в строке и заменяющий найденные подстроки замещающей подстрокой.

Метод объекта String , использующий регулярное выражение или фиксированную строку для разделения строки на массив подстрок.

Если Вам необходимо выяснить, найден ли патэрн в строке, используйте методы test или search; для получения большего количества информации (и более медленного выполнения) используйте методы exec или match. Если Вы используете exec или match и если совпадение найдено, эти методы возвращают массив и обновляют свойства ассоциированного объекта регулярного выражения и предопределённого объекта регулярного выражения, RegExp. Если совпадения нет, метод exec возвращает значение null (которое конвертируется в false).
В следующем примере скрипт использует метод exec для поиска совпадения в строке:
Если Вам не нужен доступ к свойствам регулярного выражения, можно создать myArray таким скриптом: Если Вы хотите иметь возможность рекомпиляции регулярного выражения, то вот ещё один скрипт:

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

Объект Свойство или Индекс Описание В данном примере

Совпавшая строка и все запомненные подстроки.

Индекс с базой 0 совпадения в строке ввода.

Последние совпавшие символы.

Индекс, по которому находится начало следующего совпадения.

Последние совпавшие символы.

Подстрока, предшествующая самому последнему совпадению.

Подстрока, идущая после самого последнего совпадения.

Метод search в JavaScript - Регулярные выражения - Введение - Объект String

Урок №6 Метод search - Регулярные выражения - Цифра

Количество просмотров : 1289

Метод search позволяет работать с регулярными выражениями .

Что такое регулярные выражения ?

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

Метод search - Регулярные выражения - Синтаксис

Он также ищет совпадение в строке и возвращает позицию (целое число), с которой оно начинается .

Если совпадений не найдено, метод search возвращает -1 .

Метод search используется при работе с регулярными выражениями.

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

Попробуем найти слово в произвольной строке.

Для наглядности разберем подробнее этот пример - посмотрим, как здесь работает javascript :

var result = "Завтра мы поедем в Крым" . искать ( /мы/ );

Итак, в примере было создано регулярное выражение (шаблон) /мы/ , которое поместили в переменную regular и которое с помощью метода search искали в строке: "Завтра мы поедем в Крым" .

В результате JavaScript выдал нам цифру 7 - это позиция, с которой начинается совпадение шаблона в строке.

Метод search - Регулярные выражения - \d - Цифра

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

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

Для тех, кто не знает: почтовый индекс городов России состоит из шести цифр и не содержит букв.

Таким образом, с помощью регулярных выражений и метода search , нужно будет определить, есть ли в строке последовательность из шести цифр от 0 до 9 .

В регулярных выражениях подобные вещи закодированы. Цифра от 0 до 9 в регулярных выражениях представлена, как \d (обратный слэш и буква d).

И снова давайте посмотрим, как в данном случае работает javascript :

var result = "Индекс города Воронеж 394000" . искать ( последовательность из шести цифр от 0 до 9 );


В примере было указано регулярное выражение \d (то есть какая-либо цифра) шесть раз . Таким образом, мы искали последовательно расположенных, шесть цифр от 0 до 9

В результате Вы увидите число 22 - это индекс (порядковый номер)цифры 3 - той, с которой начинается последовательность.

Теперь рассмотрим пример, где почтовый индекс введен с ошибкой.

Если же пользователь сделает ошибку и введет, например, 5 цифр, или вместо цифры - букву, то в результате мы увидим -1 . Это «говорит» о том, что в строке нет последовательности из шести подряд расположенных цифр, то есть в ней не найден почтовый индекс России.

Ситуация, при которой пользователь может ввести 7, 8 или более цифр будет разрешена в конце следующего урока, где будут использованы регулярные выражения ^ и $ - Начала и Конца строки.

Для наглядности и дополнительной практики в работе с кодом javascript , можно реализовать следующее:

Оптимизировать предыдущий пример и попросить у пользователя при помощи метода prompt ввести почтовый индекс из шести цифр. Потом сделать проверку, используя условие if-else, на предмет правильности ввода требуемой информации. Попробуйте в результате ввести 5 цифр или 5 цифр и букву.

Но этот пример не доработан. Да, в нем нельзя ввести менее 6 цифр в качестве почтового индекса, а больше 6 - можно . Кроме этого вместе с индексом более, чем из шести цифр можно ввести какой-либо текст и javascript не будет исключать и этот вариант. Попробуйте поэкспериментировать.

Как это сделать? Как добиться того, чтобы пользвотель вводил исключительно последовательность из шести цифр и ничего более?

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

Wiki-учебник по веб-технологиям: JavaScript/РегулярныеВыражения .

Регулярные выражения являются патэрнами, используемыми при поиске совпадений комбинаций символов в строках. В JavaScript регулярные выражения являются также объектами. Эти патэрны используются вместе с методами exec и test объекта **RegExp** и с методами match, replace, search и split объекта String.
В этой главе рассматриваются регулярные выражения JavaScript.

JavaScript 1.1 и ранее.

Регулярные выражения недоступны в JavaScript 1.1 и более ранних версиях.

В этой главе имеются следующие разделы:

  • Создание Регулярного Выражения

  • Написание Патэрна Регулярного Выражения

  • Работа с Регулярными Выражениями

  • Примеры

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

Вы конструируете регулярное выражение одним из двух способов:

  • Используя литерал регулярного выражения:

2. Написание патэрна регулярного выражения

Патэрн регулярного выражения состоит из обычных символов, таких как /abc/ или из комбинаций обычных и специальных символов, таких как /ab*c/ или /Chapter (\d+)\.\d*/. В последнем примере есть скобки, которые используются в качестве запоминающего устройства. Совпадение этой части патэрна запоминается для последующего использования, как описано в разделе «Использование Совпадений Подстрок в Скобках».

2.1. Использование простых патэрнов

Простые патэрны составляются из символов, для которых Вы ищете прямое совпадение. Например, патэрн /abc/ совпадает в строке только с точными комбинациями указанных символов 'abc' в указанном порядке. Такое совпадение произойдёт в строках “Hi, do you know your abc's?” и “The latest airplane designs evolved from slabcraft.” В обоих случаях совпадение произойдёт с подстрокой 'abc'. В строке “Grab crab” совпадения не будет, поскольку она не содержит подстроки 'abc'.

2.2. Использование специальных символов

Если при поиске требуется нечто большее, чем простое совпадение, например, найти один или более символов b или найти пробел, в патэрн включаются специальные символы. Например, патэрн /ab*c/ совпадает с любой комбинацией символов, в которой после одиночной 'a' идёт нуль или более символов 'b» (* означает 0 или более вхождений предшествующего элемента/символа) и сразу за ними – 'c'. В строке “cbbabbbbcdebc” этот патэрн совпадёт с подстрокой 'abbbbc'.

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

Таблица 4.1 Специальные символы в регулярных выражениях

Например, /^A/ не совпадает с 'A' в строке “an A”, но совпадает с первым 'A' в строке “An A”.

Символ Значение
\
$ Совпадает с концом ввода. Если многострочный флаг установлен в true, совпадает также непосредственно перед символом разрыва строки.

Например, /t$/ не совпадает с 't' в строке “eater”, но совпадает с в строке “eat”.

* Предшествующий символ совпадает 0 или более раз.

Например, /bo*/ совпадает с 'boooo' в строке “A ghost booooed” и с 'b' в “A bird warbled”, но не совпадает ни с чем в строке “A goat grunted”.

+ Предшествующий символ совпадает 1 или более раз. Эквивалентно <1,>.

Например, /a+/ совпадает с 'a' в “candy” и со всеми 'a' в “caaaaaaandy”.

? Предшествующий символ совпадает 0 или 1 раз.

Например, /e?le?/ совпадает с 'el' в “angel” и с 'le' в “angle.”

Если используется сразу после квантификаторов *, +, ? или <>, делает квантификатор нежадным (совпадает минимальное число раз), что противоположно действию по умолчанию, когда квантификатор – жадный (совпадает максимальное число раз).

Используется также во вперёдсмотрящих/lookahead утверждениях, описанных в пунктах о x(?=y) и x(?!y) в этой таблице.

. (Десятичная точка) совпадает с любым одиночным символом, исключая символ новой строки.

Например, /.n/ совпадает с 'an' и с 'on' в “nay, an apple is on the tree”, но не с 'nay'.

(x) Совпадает с 'x' и запоминает совпадение. Это называется «захватывающие скобки».

Например, /(foo)/ совпадает с 'foo', и запоминает её, в “foo bar.” Совпадающая подстрока может быть вызвана из элементов результирующего массива [1], . [n].

(?:x) Совпадает с 'x', но не запоминает совпадение. Это называется «незахватывающие скобки». Совпадающая подстрока не может быть вызвана из элементов результирующего массива [1], . [n].
x(?=y) Совпадает с 'x' только в том случае, если после 'x' следует 'y'. Например, /Jack(?=Sprat)/ совпадает с 'Jack' только тогда, когда следом идёт 'Sprat'. /Jack(?=Sprat|Frost)/ совпадает с 'Jack' только тогда, когда следом идёт 'Sprat' или 'Frost'. Однако ни 'Sprat', ни 'Frost' не являются частью результата совпадения.
x(?!y) Совпадает с 'x' только в том случае, если после 'x' не следует 'y'. Например, /\d+(?!\.)/ совпадает с числом только в том, случае, если после него нет десятичной точки. регулярное выражение /\d+(?!\.)/.exec(«3.141») совпадает с 141, но не совпадает с 3.141.
x|y Совпадает с 'x' или 'y'.

Например, /green|red/ совпадает с 'green' в “green apple” и с 'red' в “red apple.”

Где n это положительное целое. Совпадает с точно n-количеством вхождений предшествующего символа.

Например, /a<2>/ не совпадает с 'a' в “candy,” но совпадает со всеми 'a' в “caandy” и с первыми двумя 'a's в “caaandy.”

Где n это положительное целое. Совпадает с как минимум n вхождений предшествующего символа.

Например, /a <2,>не совпадает с 'a' в “candy”, но совпадает со всеми 'a' в “caandy” и в “caaaaaaandy.”

Где n и m это положительные целые. Совпадает с минимум n и с максимум m вхождений предшествующего символа.

Например, /a<1,3>/ не совпадает ни с чем в “cndy”, совпадает с 'a' в “candy”, с первыми двумя 'a' в “caandy” и с первыми тремя 'a' в “caaaaaaandy” Заметьте, что при совпадении с “caaaaaaandy”, совпадёт “aaa”, хотя оригинальная строка содержит большее количество 'a'.

[xyz] Набор символов. Совпадение с одним из символов в скобках. Можно специфицировать диапазон символов с помощью дефиса.

Например, [abcd] это то же самое, что и [a-d]. Совпадает с 'b' в “brisket” и с 'c' в “ache”.

[^xyz] Отрицание предложенного набора символов. То есть совпадает со всем, кроме того, что заключено в скобки. Можно специфицировать диапазон символов с помощью дефиса.

Например, [^abc] это то же самое, что [^a-c]. Они совпадают с 'r' в “brisket” и с 'h' в “chop.”

[\b] Совпадает с backspace (не путайте с \b).
\b Совпадает на границе слова с таким символом, как space и символ новой строки (не путайте с[\b]).

Например, /\bn\w/ совпадает с 'no' в “noonday”; /\wy\b/ совпадает с 'ly' в “possibly yesterday.”

\B Совпадает не на границе слова.

Например, /\w\Bn/ совпадает с 'on' в “noonday”, а /y\B\w/ совпадает с 'ye' в “possibly yesterday.”

\cX Где X это управляющий символ. Совпадает с управляющим символом.

Например, /\cM/ совпадает с control-M в строке.

\d Совпадает с цифровым символом. Эквивалентно [ 0–9 ].

Например, /\d/ или /[ 0–9 ]/ совпадает с '2' в “B2 is the suite number.”

\D Совпадает с любым нецифровым символом. Эквивалентно [^ 0–9 ].

Например, /\D/ или /[^ 0–9 ]/ совпадает с 'B' в “B2 is the suite number.”

\f Совпадает с символом прогона страницы/form-feed.
\n Совпадает с символом прогона строки/linefeed.
\r Совпадает с символом возврата каретки/carriage return.
\s Совпадает с одиночным пробельным символом, включая space, tab, form feed, line feed. Эквивалентно [ \f\n\r\t\v\u00A0\u2028\u2029].

Например, /\s\w*/ совпадает с ' bar' в “foo bar.”

\S Совпадает с одиночным символом, отличным от пробельного символа. Эквивалентно [ ^\f\n\r\t\v\u00A0\u2028\u2029].

Например, /\S\w*/ совпадает с 'foo' в “foo bar.”

\t Совпадает с табуляцией/tab.
\v Совпадает с вертикальной табуляцией/vertical tab.
\w Совпадает с любым алфавитным символом, включая символ подчёркивания/underscore. Эквивалентно [A-Za-z 0–9 _].

Например, /\w/ совпадает с 'a' в “apple,” с '5' в "$5.28” и с '3' в “3D.”

\W Совпадает с любым несловарным символом. Эквивалентно [^A-Za-z 0–9 _].

Например, /\W/ или /[^$A-Za-z 0–9 _]/ совпадает с '%' в «50%.»

\n Где n это положительное целое. Обратная ссылка на последнюю подстроку, совпавшую с n вхождений символа в скобках в регулярном выражении (включая левые скобки). (Здесь не совсем чётко. Прим. перев.)

Например, /apple(,)\sorange\1/ совпадает с 'apple, orange,' в “apple, orange, cherry, peach.”

\0 Совпадает с символом NUL. Не вводите после него других цифр.
\xhh Совпадает с символом с 16-ричным кодом hh (две 16-ричные цифры)
\uhhhh Совпадает с символом с 16-ричным кодом hhhh (четыре 16-ричные цифры).

2.3. Использование скобок

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

Например, патэрн /Chapter (\d+)\.\d*/ иллюстрирует использование дополнительных escape-ированных и специальных символов и указывает, что эта часть патэрна должна быть запомнена. Он совпадает точно с символами 'Chapter ' с последующими одним или более цифровыми символами (\d означает любой цифровой символ, а + означает 1 или более раз), с последующей десятичной точкой (которая сама по себе является специальным символом; предварение десятичной точки символом \ означает, что патэрн обязан искать специальный литеральный символ '.'), с последующим любым цифровым символом 0 или более раз(\d означает цифровой символ, * означает 0 или более раз). Кроме того, используются скобки для запоминания первых совпавших цифровых символов.

Этот патэрн будет найден в строке «Open Chapter 4.3, paragraph 6", и '4' будет запомнена. Патэрн не будет найден в строке «Chapter 3 and 4", поскольку здесь отсутствует десятичная точка после цифры '3'.

Чтобы найти совпадение с подстрокой без запоминания совпавшей части, предваряйте патэрн внутри скобок символами ?:. Например, (?:\d+) совпадает с единицей или числовым символом, но не запоминает совпавшие символы.

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

Регулярные выражения используются с методами test и exec объекта **RegExp** и с методами match, replace, search и split объекта String.Эти методы рассматриваются в книге Ядро JavaScript. Справочник.

Таблица 4.2 Методы, Использующие Регулярные Выражения.

Метод Описание
exec Метод объекта RegExp, выполняющий поиск совпадения в строке. Возвращает массив информации.
test Метод объекта RegExp, тестирующий на совпадение в строке. Возвращает true или false.
match Метод объекта String, выполняющий поиск совпадения в строке. Возвращает массив информации или null при отсутствии совпадений.
search Метод объекта String, тестирующий на совпадение в строке. Возвращает индекс совпадения или -1, если поиск завершился ничем.
replace Метод объекта String, выполняющий поиск совпадения в строке и замещающий совпавшую подстроку замещающей подстрокой.
split Метод объекта String, использующий регулярное выражение или фиксированную строку для разбивки строки на массив подстрок.

Если Вам нужно знать, найден ли патэрн в строке, используйте методы test или search; для получения большей информации (но при замедлении выполнения) используйте методы exec или match. Если Вы используете методы exec или match и если совпадение найдено, эти методы возвращают массив и обновляют свойства объекта регулярного выражения, а также предопределённого объекта регулярного выражения, RegExp. Если совпадение не найдено, метод exec возвращает null (которое конвертируется в false).

В следующем примере скрипт использует метод exec для поиска совпадения в строке:

Если Вам не нужен доступ к свойствам регулярного выражения, альтернативным способом создания myArray будет такой скрипт:

Если Вы хотите сконструировать регулярное выражение из строки, вот ещё один скрипт:

Highlighter for JAVSCRIPT not found

С помощью этих скриптов находится совпадение и возвращается массив и обновляются свойства, показанные в следующей таблице.

Мастер Йода рекомендует:  Управление сценариями просмотра Web-страниц Javascript
Добавить комментарий