Файл: Объект RegExp Объект типа RegExp, или, короче, регулярное выражение, можно создать двумя путями.docx
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 11.12.2023
Просмотров: 23
Скачиваний: 1
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
Регулярные выражения в javascript имеют особую краткую форму и стандартный PCRE-синтаксис. Работают они через специальный объект RegExp. Кроме того, у строк есть свои методы search,match,replace, но чтобы их понять - разберем сначала RegExp.
Объект RegExp
Объект типа RegExp, или, короче, регулярное выражение, можно создать двумя путями
/pattern/флаги
new RegExp("pattern"[, флаги])
pattern - регулярное выражение для поиска (о замене - позже), а флаги - строка из любой комбинации символов g(глобальный поиск), i(регистр неважен) и Ш(многострочный поиск).
Первый способ используется часто, второй - иногда. Например, два таких вызова эквивалентны:
var reg = /ab+c/i
var reg = new RegExp("ab+c", "i")
При втором вызове - т.к регулярное выражение в кавычках, то нужно дублировать \// эквивалентны
re = new RegExp("\\w+")
re = /\w+/
При поиске можно использовать большинство возможностей современного PCRE-синтаксиса.
Спецсимволы в регулярном выражении
Символ | Значение |
\ | Для обычных символов - делает их специальными. Например, выражение /s/ ищет просто символ 's'. А если поставить \ перед s, то /\s/ уже обозначает пробельный символ.И наоборот, если символ специальный, например *, то \ сделает его просто обычным символом "звездочка". Например, /a*/ ищет 0 или больше подряд идущих символов 'a'. Чтобы найти а со звездочкой 'a*' - поставим \ перед спец. символом: /a\*/. |
^ | Обозначает начало входных данных. Если установлен флаг многострочного поиска ("m"), то также сработает при начале новой строки.Например, /^A/ не найдет 'A' в "an A", но найдет первое 'A' в "An A." |
$ | Обозначает конец входных данных. Если установлен флаг многострочного поиска, то также сработает в конце строки.Например, /t$/ не найдет 't' в "eater", но найдет - в "eat". |
* | Обозначает повторение 0 или более раз. Например, /bo*/ найдет 'boooo' в "A ghost booooed" и 'b' в "A bird warbled", но ничего не найдет в "A goat grunted". |
+ | Обозначает повторение 1 или более раз. Эквивалентно {1,}. Например, /a+/ найдет 'a' в "candy" и все 'a' в "caaaaaaandy". |
? | Обозначает, что элемент может как присутствовать, так и отсутствовать. Например, /e?le?/ найдет 'el' в "angel" и 'le' в "angle."Если используется сразу после одного из квантификаторов *, +, ?, или {}, то задает "нежадный" поиск (повторение минимально возможное количество раз, до ближайшего следующего элемента паттерна), в противоположность "жадному" режиму по умолчанию, при котором количество повторений максимально, даже если следующий элемент паттерна тоже подходит.Кроме того, ? используется в предпросмотре, который описан в таблице под (?=), (?!), и (?: ). |
. | (Десятичная точка) обозначает любой символ, кроме перевода строки: \n \r \u2028 or \u2029. (можно использовать [\s\S] для поиска любого символа, включая переводы строк). Например, /.n/ найдет 'an' и 'on' в "nay, an apple is on the tree", но не 'nay'. |
(x) | Находит x и запоминает. Это называется "запоминающие скобки". Например, /(foo)/ найдет и запомнит 'foo' в "foo bar." Найденная подстрока хранится в массиве-результате поиска или в предопределенных свойствах объекта RegExp: $1, ..., $9.Кроме того, скобки объединяют то, что в них находится, в единый элемент паттерна. Например, (abc)* - повторение abc 0 и более раз. |
(?:x) | Находит x, но не запоминает найденное. Это называется "незапоминающие скобки". Найденная подстрока не сохраняется в массиве результатов и свойствах RegExp.Как и все скобки, объединяют находящееся в них в единый подпаттерн. |
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 - положительное целое число. Находит ровно n повторений предшествующего элемента. Например, /a{2}/ не найдет 'a' в "candy," но найдет оба a в "caandy," и первые два a в "caaandy." |
{n,} | Где n - положительное целое число. Находит n и более повторений элемента. Например, /a{2,} не найдет 'a' в "candy", но найдет все 'a' в "caandy" и в "caaaaaaandy." |
{n,m} | Где n и m - положительные целые числа. Находят от n до m повторений элемента. |
[xyz] | Набор символов. Находит любой из перечисленных символов. Вы можете указать промежуток, используя тире. Например, [abcd] - то же самое, что [a-d]. Найдет 'b' в "brisket", а также 'a' и 'c' в "ache". |
[^xyz] | Любой символ, кроме указанных в наборе. Вы также можете указать промежуток. Например, [^abc] - то же самое, что [^a-c]. Найдет 'r' в "brisket" и 'h' в "chop." |
[\b] | Находит символ backspace. (Не путать с \b.) |
\b | Находит границу слов (латинских), например пробел. (Не путать с [\b]). Например, /\bn\w/ найдет 'no' в "noonday"; /\wy\b/ найдет 'ly' в "possibly yesterday." |
\B | Обозначает не границу слов. Например, /\w\Bn/ найдет 'on' в "noonday", а /y\B\w/ найдет 'ye' в "possibly yesterday." |
\cX | Где X - буква от A до Z. Обозначает контрольный символ в строке. Например, /\cM/ обозначает символ Ctrl-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,\r,\n | Соответствующие спецсимволы form-feed, line-feed, перевод строки. |
\s | Найдет любой пробельный символ, включая пробел, табуляцию, переводы строки и другие юникодные пробельные символы. Например, /\s\w*/ найдет ' bar' в "foo bar." |
\S | Найдет любой символ, кроме пробельного. Например, /\S\w*/ найдет 'foo' в "foo bar." |
\t | Символ табуляции. |
\v | Символ вертикальной табуляции. |
\w | Найдет любой словесный (латинский алфавит) символ, включая буквы, цифры и знак подчеркивания. Эквивалентно [A-Za-z0-9_]. Например, /\w/ найдет 'a' в "apple," '5' в "$5.28," и '3' в "3D." |
\W | Найдет любой не-(лат.)словесный символ. Эквивалентно [^A-Za-z0-9_]. Например, /\W/ и /[^$A-Za-z0-9_]/ одинаково найдут '%' в "50%." |
\n | где n - целое число. Обратная ссылка на n-ю запомненную скобками подстроку. Например, /apple(,)\sorange\1/ найдет 'apple, orange,' в "apple, orange, cherry, peach.". За таблицей есть более полный пример. |
\0 | Найдет символ NUL. Не добавляйте в конец другие цифры. |
\xhh | Найдет символ с кодом hh (2 шестнадцатиричных цифры) |
\uhhhh | Найдет символ с кодом hhhh (4 шестнадцатиричных цифры). |
Пример 1:
Задача: разбить строку, содержащую IP адрес ipv4 на компоненты
Вход: текстовая строка четыре числа разделённые точкой
Выход: четыре числа компоненты адреса
var myRe = /(\d\d?\d?)\.(\d\d?\d?)\.(\d\d?\d?)\.(\d\d?\d?)/;
if (myRe.test('192.168.25.40'))
{
var ar = myRe.exec('192.168.25.40');
alert(ar[1] + '.' + ar[2] + '.' + ar[3] + '.' + ar[4]);
}
Пример 2
Выделение IP-адресов в тексте (IPv4)
/*
Ниже приведен пример регулярного выражения с пояснениями
( # начало группы
(?=\d+\.\d+\.\d+\.\d+) # основная часть выражения, требующая формата: число.число.число.число
(?: # начало незахватывающей группы (число 0-255 + опциональная точка)
(?: # начало незахватывающей группы (число 0-255)
25[0-5] # 250-255
| # или
2[0-4][0-9] # 200-249
| # или
1[0-9]{2} # 100-199
| # или
[1-9][0-9] # 10-99
| # или
[0-9] # 0-9
) # конец незахватывающей группы
\.? # опциональная точка
){4} # конец незахватывающей группы (число + опциональная точка), повторяется четыре раза
) # конец группы
*/
var reg = /((?=\d+\.\d+\.\d+\.\d+)(?:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])\.?){4})/g;
var sourceStr = "Это строка, которая содержит IP-адрес: '192.68.35.35',"
+ "'0.0.0.0','255.0.0.0','192.168.1.0','192.168.0.1',"
+ "'255.255.255.0','1.1.1.1','255.255.255.255','249.249.249.249',"
+ "'200.200.200.200','199.199.199.199'";
var ips = null;
while ((ips = reg.exec(sourceStr)) != null)
Log.writeLine(ips[0]);
Пример 3
Выделение IP-адресов в тексте (IPv6)
/*
Распознавание IP-адреса в формате IPv6:
2a03:1800:1:4:217:31ff:feb4:8d55
*/
var reg = /([0-9a-f]|:){1,4}(:([0-9a-f]{0,4})*){1,7}$/ig;
var sourceStr = "Эта строка содержит адрес в формате IPv6: 2a03:1800:1:4:217:31ff:feb4:8d55";
var dest = sourceStr.match(reg);
if (dest)
alert(dest[0]);
Пример 4:
Задача: замена переводов строки на пробелы
Вход: произвольная текстовая строка (например из базы) в которой могут быть пробелы
Выход: та же строка где символы перевода строк (\n\r или одиночный \n) заменяются на пробел
var myRe = /(\n(\r)?)/g;
var str = 'строка1 \n строка2 \n\r строка3 \n\r';
if (myRe.test(str))
{
var result = str.replace(myRe, ' ');
alert(result);
}
Пример 5:
Задача: разбор имени, фамилии и отчества
Вход: строка содержащая имя фимилию и отчество
Выход: три строки, содержащие имя. фамилию и отчество
var str = 'Иван Иванов Иванович';
var myRe = /([А-Яа-я]+)\s([А-Яа-я]+)\s([А-Яа-я]+)/;
if (myRe.test(str))
{
var ar = myRe.exec(str);
alert('Имя: ' + ar[1] + ' Фамилия: ' + ar[2] + ' Отчество: ' + ar[3]);
}
Пример 6
Замена неправильных символов в имени файла
/*
Список некорректных символов для имени файла:
"#", "%", "&", "{", "}", "\", "<", ">",
"*", "?", "/", "s", "$", "!", ":", "@",
"+", "|", "="
*/
var reg = /[\#\%\&\{\}\\\<\>\*\?\/\s\$\!\:\@\+\|\=]/g;
var badFileName = "!123 %%#{}|\/?*.txt";
var goodFileName = badFileName.replace(reg, "_");
alert(goodFileName);
Пример 7
Замена всех символов, кроме разрешенных
/*
Список разрешенных символов:
"a", "s", "D", "e", "c", "v", "b", "n"
*/
var reg = /[^asDecvbn]/g;
var badStr = "fdgasyyrDnnb";
var goodStr = badStr.replace(reg, "");
alert(goodStr);
Пример 8
Разбор даты и времени из лога
/*
Пример данных из Log-файла:
2016/12/27 11:48:14:527 [7672, 392] INFO Terminating: TCustomForm.Close{not HasOtherVisibleForms}
2016/12/27 11:48:14:528 [7672, 392] INFO Application.LastShowedForm: TNotifyView[]
2016/12/27 11:48:14:533 [7672,2288] INFO SendingThread::PING
2016/12/27 11:48:14:535 [7672,4684] INFO ReceivingThread::PONG
2016/12/27 11:48:14:540 [7672, 392] INFO close [node:19996385127421]
2016/12/27 11:48:14:656 [7672, 392] INFO FinalizePhenixKernel
2016/12/27 11:48:14:767 [7672,4684] INFO ReceivingThread normal exit
2016/12/27 11:48:14:797 [7672,2288] INFO SendingThread normal exit
2016/12/27 11:48:15:966 [7672, 392] INFO Конфигурация [70202972297322] не сохранена: нет подключения
2016/12/27 11:48:15:970 [7672, 392] INFO main exit
*/
var regDateTime = /(\d+\/\d+\/\d+\s\d+\:\d+\:\d+)/g;
var regDate = /(\d+\/\d+\/\d+)/g;
var regTime = /(\d+\:\d+\:\d+)/g;
var file = FileSystem.openTextFile("e:/example/log.txt");
try
{
while (!file.eof)
{
var line = Strings.trimAll(file.readLine());
if (!line)
continue;
var dateTimeStr = line.match(regDateTime);
if (!dateTimeStr)
continue;
var date = dateTimeStr[0].match(regDate)[0].split("/");
var time = dateTimeStr[0].match(regTime)[0].split(":");
var year = date[0];
var month = date[1];
var day = date[2];
var hour = time[0];
var minute = time[1];
var second = time[2];
Log.writeLine("Результат разбора даты");
Log.writeLine("год: " + year + " месяц: " + month + " день: " + day);
Log.writeLine("Результат разбора времени");
Log.writeLine("часы: " + hour + " минуты: " + minute + " секунды: " + second);
}
}
finally
{
file.close();
}
Пример 9
Замена ',' на ';'
varreg = /\,/g;
varsourceStr = "Это некоторая строка, содержащая символ ','";
vardestStr = sourceStr.replace(reg, ";");
alert(destStr);
Пример 10
Распознавание телефонного номера
varreg = /((8|\+7)[\- ]?)?(\(?\d{3,5}\)?[\- ]?)?[\d\- ]{5,10}/g;
varsourceStr = "Данная строка содержит несколько номеров в разных форматах: "
+ "'+79261234567', "
+ "'89261234567', "
+ "'79261234567', "
+ "'+7 926 123 45 67', "
+ "'8(926)123-45-67', "
+ "'123-45-67', "
+ "'9261234567', "
+ "'79261234567', "
+ "'(495)1234567', "
+ "'(495) 123 45 67', "
+ "'89261234567', "
+
"'8-926-123-45-67', "
+ "'8 927 1234 234', "
+ "'8 927 12 12 888', "
+ "'8 927 12 555 12', "
+ "'+7 (4932) 23-08-64', "
+ "'8 927 123 8 123'";
varphones = null;
while ((phones = reg.exec(sourceStr)) != null)
Log.writeLine(phones[0]);
Пример 11
Обработка ошибок phx.err
Вычленение версий клиента и сервера, имени пользователя
varphxErrStr =
"2016/01/20 16:59:36:563 [3204,3976] ERROR v5.2.125/5.2.126 fav: Невозможно перенести узел[70202975761937] сам в себя"
+ "inform.adt.InformException: Невозможно перенести узел[70202975761937] сам в себя "
+ "inform.adt.InformException"
+ " at inform.agent.mtd.nodes.Node.changeParent(Node.java:1268)"
+ " at inform.agent.mtd.nodes.Node.changeParent(Node.java:1294)"
+ " at inform.agent.mtd.nodes.BasicNode.changeParent(BasicNode.java:882)"
+ " at inform.agent.mtd.request.ModifyNode.modifyNode(ModifyNode.java:92)...";
varreg = /(5\.2\.\d+)\/(5\.2\.\d+)\s([A-z0-9]+)/;
varres = phxErrStr.match(reg);
if (res)
{
Log.writeLine("Версия клиента: " + res[1]);
Log.writeLine("Версия сервера: " + res[2]);
Log.writeLine("Имя пользователя: " + res[3]);
}
Пример 12
Применение шаблона ${<выражение JS>}
Данный пример показывает, как можно применять разные шаблоны для формирования выходных документов на основании одних и тех же данных.
functionevaluate(context, evalStr)
{
with (context)
returneval(evalStr);
}
functionapplyTemplate(template, contextObject)
{
returntemplate.replace(/\${([^}]+)}/g, function(_, expr) {
returnevaluate(contextObject, expr);
});
}
functionjsTemplateRecognition()
{
/*
Применение шаблона ${<выражение JS>}
*/
vartemplate1 = "Фирма '${name}' имеет контактый телефон '${phone}'";
vartemplate2 = "Наименование предприятия: ${name} \nКонтактный телефон: ${phone}";
//В данном примере объект record формируется вручную, но на практике может
//формироваться на основе данных из таблицы
varrecord = {};
record["name"] = "ООО Рога и копыта";
record["phone"] = "(4932) 12-34-56";
Log.writeLine(applyTemplate(template1, record));
Log.writeLine(applyTemplate(template2, record));
}