Назад Оглавление Индекс Вперёд |
Ядро JavaScript 1.5. Руководство по Использованию. |
Регулярные выражения являются патэрнами, используемыми при
поиске совпадений комбинаций символов в строках. В JavaScript регулярные
выражения являются также объектами. Эти патэрны используются вместе с методами exec
и test объекта RegExp и с методами match, replace, search и split объекта String.
В этой главе рассматриваются регулярные выражения JavaScript.
Регулярные выражения недоступны в JavaScript 1.1 и более ранних версиях.
В этой главе имеются следующие разделы:
Вы конструируете регулярное выражение одним из двух способов:
Патэрн регулярного выражения состоит из обычных символов, таких как /abc/, или из комбинаций обычных и специальных символов, таких как /ab*c/ или /Chapter (\d+)\.\d*/. В последнем примере есть скобки, которые используются в качестве запоминающего устройства. Совпадение этой части патэрна запоминается для последующего использования, как описано в разделе Использование Совпадений Подстрок в Скобках.
Простые патэрны составляются из символов, для которых Вы
ищете прямое совпадение. Например, патэрн /abc/ совпадает в строке только с
точными комбинациями указанных символов 'abc' в указанном порядке. Такое
совпадение произойдёт в строках "Hi, do you know your abc's?" и "The latest airplane designs evolved from slabcraft."
В обоих случаях совпадение произойдёт с подстрокой 'abc'. В строке "Grab crab"
совпадения не будет, поскольку она не содержит подстроки 'abc'.
Если при поиске требуется нечто большее, чем простое совпадение, например, найти один или более символов b или найти пробел, в патэрн включаются специальные символы. Например, патэрн /ab*c/ совпадает с любой комбинацией символов, в которой после одиночной 'a' идёт нуль или более символов 'b" (* означает 0 или более вхождений предшествующего элемента/символа) и сразу за ними - 'c'. В строке "cbbabbbbcdebc" этот патэрн совпадёт с подстрокой 'abbbbc'.
В следующей таблице дан полный список и и описание
специальных символов, используемых в регулярных выражениях.
Скобки вокруг любой части патэрна регулярного выражения вызывают запоминание этой части совпавшей подстроки. Затем эта подстрока может быть вызвана для последующего использования, как описано в разделе Использование Совпадений Подстроки в Скобках.
Например, патэрн /Chapter (\d+)\.\d*/ иллюстрирует
использование дополнительных escape-ированных и специальных символов и
указывает, что эта часть патэрна должна быть запомнена. Он совпадает точно с
символами 'Chapter ' с последующими одним или более цифровыми символами (\d
означает любой цифровой символ, а + означает 1 или более раз), с последующей
десятичной точкой (которая сама по себе является специальным символом;
предварение десятичной точки символом \ означает, что патэрн обязан искать
специальный литеральный символ '.'), с последующим любым цифровым символом 0 или
более раз(\d означает цифровой символ, * означает 0 или более раз). Кроме того,
используются скобки для запоминания первых совпавших цифровых символов.
Этот патэрн будет найден в строке "Open Chapter 4.3, paragraph 6",
и '4' будет запомнена. Патэрн не будет найден в строке "Chapter 3 and 4",
поскольку здесь отсутствует десятичная точка после цифры '3'.
Чтобы найти совпадение с подстрокой без запоминания
совпавшей части, предваряйте патэрн внутри скобок символами ?:. Например, (?:\d+)
совпадает с единицей или числовым символом, но не запоминает совпавшие символы.
Регулярные выражения используются с методами test и exec объекта RegExp и с методами match, replace, search и split объекта String.Эти методы рассматриваются в книге Ядро JavaScript. Справочник.
Если Вам нужно знать, найден ли патэрн в строке,
используйте методы test или search; для получения большей информации (но при
замедлении выполнения) используйте методы exec или match. Если Вы используете
методы exec или match и если совпадение найдено, эти методы возвращают массив и
обновляют свойства объекта регулярного выражения, а также предопределённого
объекта регулярного выражения, RegExp. Если совпадение не найдено, метод exec
возвращает null (которое конвертируется в false).
В следующем примере скрипт использует метод exec для поиска совпадения в строке:
<SCRIPT LANGUAGE="JavaScript1.2">
myRe=/d(b+)d/g;
myArray = myRe.exec("cdbbdbsbz");
</SCRIPT>
Если Вам не нужен доступ к свойствам регулярного выражения,
альтернативным способом создания myArray будет такой скрипт:
<SCRIPT LANGUAGE="JavaScript1.2">
myArray = /d(b+)d/g.exec("cdbbdbsbz");
</SCRIPT>
Если Вы хотите сконструировать регулярное выражение из строки, вот ещё один скрипт:
<SCRIPT LANGUAGE="JavaScript1.2">
myRe= new RegExp ("d(b+)d", "g");
myArray = myRe.exec("cdbbdbsbz");
</SCRIPT>
С помощью этих скриптов находится совпадение и
возвращается массив и обновляются свойства, показанные в следующей таблице.
Объект |
Свойство или Индекс | Описание | В этом примере: |
---|---|---|---|
myArray |
|||
index |
|||
input |
|||
[0] | |||
myRe |
lastIndex | Индекс, начиная с которого стартует следующее совпадение. (Это свойство установлено только тогда, когда регулярное выражение использует опцию g, описанную в разделе Выполнение Глобального Поиска, Игнорирование Регистра и Рассмотрение Многострочного Ввода.) | |
source |
Текст патэрна. Обновляется в момент создания регулярного выражения, не исполняется. |
Как показано во второй форме этого примера, Вы можете
использовать регулярное выражение, созданное с помощью инициализатора объекта,
без присвоения его переменной. Если Вы всё же это сделаете, каждое вхождение
будет новым регулярным выражением. Исходя из этого, если Вы используете форму
без присвоения выражения переменной, Вы не сможете затем получить доступ к
свойствам этого регулярного выражения. Например, у Вас есть скрипт:
<SCRIPT LANGUAGE="JavaScript1.2">
myRe=/d(b+)d/g;
myArray = myRe.exec("cdbbdbsbz");
document.writeln("The value of lastIndex is " + myRe.lastIndex);
</SCRIPT>
Если Ваш скрипт, однако, будет таким:
<SCRIPT LANGUAGE="JavaScript1.2">
myArray = /d(b+)d/g.exec("cdbbdbsbz");
document.writeln("The value of lastIndex is " + /d(b+)d/g.lastIndex);
</SCRIPT>
Вхождения /d(b+)d/g в этих двух операторах являются разными объектами регулярного выражения и, соответственно, имеют разные значения свойства lastIndex. Если Вам нужен доступ к свойствам регулярного выражения, созданного с помощью инициализатора объекта, Вы должны сначала присвоить это выражение переменной.
Включение скобок в патэрн регулярного выражения вызывает запоминание соответствующего подсовпадения. Например, /a(b)c/ совпадает с символами 'abc' и запоминает 'b'. Чтобы вызвать эту подстроку в скобках, используйте Array-элементы [1], ..., [n].
Количество подстрок, заключённых в скобки, не
ограничивается. Возвращаемый массив содержит все найденные совпадения. Следующие
примеры иллюстрируют использование подстрок в скобках.
В этом скрипте используется метод replace для изменения-переключения слов в строке. Для замещающего текста в скрипте используется $1 и $2 для обозначения первой строки и второй подстроки в скобках.
<SCRIPT LANGUAGE="JavaScript1.2">
re = /(\w+)\s(\w+)/;
str = "John Smith";
newstr = str.replace(re, "$2, $1");
document.write(newstr)
</SCRIPT>
Будет напечатано "Smith, John".
Здесь RegExp.input устанавливается событием Change. В функции getInfo метод exec, вызываемый с использованием сокращённой нотации (), использует значение RegExp.input в качестве аргумента.
<SCRIPT LANGUAGE="JavaScript1.2">
function getInfo(){
a = /(\w+)\s(\d+)/();
window.alert(a[1] + ", your age is " + a[2]);
}
</SCRIPT>
Enter your first name and your age, and then press Enter.
<FORM>
<INPUT TYPE="text" NAME="NameAge" onChange="getInfo(this);">
</FORM>
Регулярные выражения могут иметь три опции-флага, дающие
возможность выполнять глобальный и нечувствительный к регистру поиск. Для
глобального поиска используйте флаг g
. Для поиска без учёта
регистра используйте флаг i
. Для многострочного поиска - флаг m
.
Эти флаги могут использоваться независимо или вместе в любом порядке и являются
частью регулярного выражения.
Для включения флага используется следующий синтаксис:
re = /pattern/flags
re = new RegExp("pattern", ["flags"])
Обратите внимание, что флаги интегрированы в регулярное
выражение. Они не могут быть позднее добавлены или удалены.
Например, re = /\w+\s/g создаёт регулярное
выражение, которое ищет один или более символов с последующим пробелом по всей строке.
<SCRIPT LANGUAGE="JavaScript1.2">
re = /\w+\s/g;
str = "fee fi fo fum";
myArray = str.match(re);
document.write(myArray);
</SCRIPT>
Отобразится ["fee ", "fi ", "fo "]. В этом примере Вы можете заменить строку:
re = new RegExp("\\w+\\s", "g");
и получить аналогичный результат.
Флаг m используется flag для специфицирования того, что
многострочный ввод должен рассматриваться как несколько строк. Если используется
флаг m, то ^ и $ совпадают в начале и в конце любой строки общей строки ввода,
вместо начала и конца всей строки ввода.
Несколько примеров использования регулярных выражений.
В этом примере показано форматирование регулярного
выражения и использование методов string.split() и string.replace(). Очищается
необработанная строка ввода, содержащая имена (сначала имя, потом фамилия),
разделённые пробелами, табуляцией и одиночным символом "точка с запятой".
Наконец, имена и фамилии меняются местами (сначала - фамилия) и список сортируется.
<SCRIPT LANGUAGE="JavaScript1.2">
// Строка names содержит несколько пробелов и табуляций,
// и может содержать несколько пробелов между первым и последним именем.
names = new String ( "Harry Trump ;Fred Barney; Helen Rigby ;\
Bill Abel ;Chris Hand ")
document.write ("---------- Original String" + "<BR>" + "<BR>");
document.write (names + "<BR>" + "<BR>");
// Подготавливаются два патэрна регулярных выражения и массив для хранения.
// Строка делится на элементы массива.
// pattern: возможен пробел, затем точка с запятой, затем пустое
пространство
pattern = /\s*;\s*/;
// Строка разбивается на куски, разделённые патэрном, и
// эти куски сохраняются в массиве nameList
nameList = names.split (pattern);
// Новый pattern: один или более символов, затем пробелы, затем символы.
// Используются скобки для "запоминания" части патэрна.
// Запомненная часть будет использоваться позднее.
pattern = /(\w+)\s+(\w+)/;
// Новый массив для содержания имён.
bySurnameList = new Array;
// Выводит массив имён и заполняет новый массив
// именами, разделёнными запятыми, сначала - фамилия.
//
// Метод replace удаляет любое совпадение с патэрном
// и замещает его запомненной строкой - второй запомненной частью,
// после которой идёт запятая, пробел и первая запомненная часть.
//
// Переменные $1 и $2 ссылаются на части,
// запомненные при совпадении патэрна.
document.write ("---------- After Split by Regular Expression" + "<BR>");
for ( i = 0; i < nameList.length; i++) {
document.write (nameList[i] + "<BR>");
bySurnameList[i] = nameList[i].replace (pattern, "$2, $1")
}
// Отображается новый массив.
document.write ("---------- Names Reversed" + "<BR>");
for ( i = 0; i < bySurnameList.length; i++) {
document.write (bySurnameList[i] + "<BR>")
}
// Сортируется по фамилии, затем выводится отсортированный массив.
bySurnameList.sort();
document.write ("---------- Sorted" + "<BR>");
for ( i = 0; i < bySurnameList.length; i++) {
document.write (bySurnameList[i] + "<BR>")
}
document.write ("---------- End" + "<BR>")
В этом примере пользователь вводит телефонный номер. Когда
нажимается Enter, скрипт проверяет правильность ведённого номера. Если номер
введён правильно (соответствует последовательности символов, специфицированной
регулярным выражением), скрипт выводит окно с подтверждением и благодарностью.
Если номер введён неправильно, скрипт выводит окно, информирующее пользователя,
что номер введён неправильно.
Регулярное выражение ищет 0 или более открывающих скобок \(?
с последующими тремя цифрами \d{3}, с последующими 0 или более закрывающими
скобками \)?, с последующим тире, слэшем или или десятичной точкой и, если
найдёт, запоминает символ ([-\/\.]), последующие три цифры \d{3}, тире, слэш
или десятичную точку \1, с последующими 4 цифрами\d{4}.
Событие Change активируется, когда пользователь нажимает Enter,
и устанавливает значение RegExp.input.
<HTML>
<SCRIPT LANGUAGE = "JavaScript1.2">
re = /\(?\d{3}\)?([-\/\.])\d{3}\1\d{4}/;
function testInfo() {
OK = re.exec();
if (!OK)
window.alert (RegExp.input +
" isn't a phone number with area code!")
else
window.alert ("Thanks, your phone number is " + OK[0])
}
Enter your phone number (with area code) and then press Enter.
<FORM>
<INPUT TYPE="text" NAME="Phone" onChange="testInfo(this);">
</FORM>