Регулярні вирази і спеціальні символи
Регулярні вирази в javascript мають особливу коротку форму і стандартний PCRE-синтаксис.
Працюють вони через спеціальний об'єкт RegExp.
Крім того, у рядків є свої методи search, match, replace, але щоб їх зрозуміти - розберемо-таки спочатку RegExp.
об'єкт RegExp
Об'єкт типу RegExp, або, коротше, регулярний вираз, можна створити двома шляхами
/ pattern / прапориnew RegExp ( "pattern" [, прапори])
pattern - регулярний вираз для пошуку (про заміну - пізніше), а прапори - рядок з будь-якої комбінації символів g (глобальний пошук), i (регістр не важлива) і m (багаторядковий пошук).
Перший спосіб використовується часто, другий - іноді. Наприклад, два таких виклику еквівалентні:
var reg = / ab + c / ivar 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' nor '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] - те ж саме, що [ad]. Знайде 'b' в "brisket", а також 'a' і 'c' в "ache". |
[^ Xyz] | Будь-який символ, крім зазначених у наборі. Ви також можете вказати проміжок. Наприклад, [^ abc] - те ж саме, що [^ ac]. Знайде '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." |
\ c X | Де 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. Не додавайте в кінець інші цифри. |
\ x hh | Знайде символ з кодом hh (2 шістнадцяткових цифри) |
\ u hhhh | Знайде символ з кодом hhhh (4 шістнадцяткових цифри). |
Перевірка результатів: метод test
Щоб просто перевірити, чи підходить рядок під регулярний вираз, використовується метод test:
if (/\s/.test("строка ")) {... У рядку є прогалини! ...
}
Пошук збігів: метод exec
Метод exec повертає масив і ставить властивості регулярного виразу.
Якщо збігів немає, то повертається null.
наприклад,
// Знайти одну d, за якою слідує 1 або більше b, за якими одна d// Запам'ятати знайдені b і наступну за ними d
// Регістронезавісімого пошук
var myRe = / d (b +) (d) / ig;
var myArray = myRe.exec ( "cdbBdbsbz");
В результаті виконання скрипта будуть такі результати:
об'єкт | Властивість / Індекс | описи | приклад |
myArray | Вміст myArray. | [ "dbBd", "bB", "d"] | |
index | Індекс збігу (від 0) | 1 | |
input | Вихідний рядок. | cdbBdbsbz | |
[0] | Останні збіглися символи | dbBd | |
[1], ... [n] | Збіги у вкладених дужках, якщо є. Число вкладених дужок не обмежена. | [1] = bB
[2] = d |
|
myRe | lastIndex | Індекс, з якого починати наступний пошук. | 5 |
ignoreCase | Показує, що був включений регістронезавісімий пошук, прапор "i". | true | |
global | Показує, що був включений прапор "g" пошуку всіх збігів. | true | |
multiline | Показує, чи був включений прапор багаторядкового пошуку "m". | false | |
source | Текст патерну. | d (b +) (d) |
Якщо в регулярному виразі включений прапор "g", Ви можете викликати метод exec багато разів для пошуку послідовних збігів у тому ж рядку. Коли Ви це робите, пошук починається на підрядку str, з індексу lastIndex. Наприклад, ось такий скрипт:
var myRe = / ab * / g;var str = "abbcdefabh";
while ((myArray = myRe.exec (str))! = null) {
var msg = "Found" + myArray [0] + ".";
msg + = "Next match starts at" + myRe.lastIndex;
print (msg);
}
Цей скрипт виведе наступний текст:
Found abb. Next match starts at 3Found ab. Next match starts at 9
У наступному прикладі функція виконує пошук по input. Потім робиться цикл по масиву, щоб подивитися, чи є інші імена.
Передбачається, що всі зареєстровані імена знаходяться в масиві А:
var A = [ "Frank", "Emily", "Jane", "Harry", "Nick", "Beth", "Rick","Terrence", "Carol", "Ann", "Terry", "Frank", "Alice", "Rick",
"Bill", "Tom", "Fiona", "Jane", "William", "Joan", "Beth"];
function lookup (input)
{
var firstName = /\w+/i.exec(input);
if (! firstName)
{
print (input + "is not a name!");
return;
}
var count = 0;
for (var i = 0; i <A.length; i ++)
{
if (firstName [0] .toLowerCase () == A [i] .toLowerCase ())
count ++;
}
var midstring = (count == 1)? "Other has": "others have";
print ( "Thanks," + count + midstring + "the same name!")
}
Строкові методи, пошук і заміна
Наступні методи працюють з регулярними виразами з рядків.
Всі методи, крім replace, можна викликати як з об'єктами типу regexp в аргументах, так і з рядками, які автоматом перетворюються в об'єкти RegExp.
Так що виклики еквівалентні:
var i = str.search (/ \ s /) var i = str.search ( "\\ s")При використанні лапок потрібно дублювати \ і немає можливості вказати прапори, тому іноді буває зручна і повна форма
var i = str.search (new RegExp ( "\\ s", "g"))Метод search (regexp)
Повертає індекс регулярного вираження в рядку, або -1.
Якщо Ви хочете знати, чи підходить рядок під регулярний вираз, використовуйте метод search (аналогічно RegExp-методи test). Щоб отримати більше інформації, використовуйте більш повільний метод match (аналогічний методу RegExp exec).
Цей приклад виводить повідомлення, в залежності від того, чи підходить рядок під регулярний вираз.
function testinput (re, str) {if (str.search (re)! = -1)
midstring = "contains";
else
midstring = "does not contain";
document.write (str + midstring + re.source);
}
Метод match (regexp)
Якщо в regexp немає прапора g, то повертає той же результат, що regexp.exec (string).
Якщо в regexp є прапор g, то повертає масив з усіма збігами.
Щоб просто дізнатися, чи підходить рядок під регулярний вираз regexp, використовуйте regexp.test (string).
Якщо Ви хочете отримати перший результат - спробуйте r egexp.exec (string).
У наступному прикладі match використовується, щоб знайти "Chapter", за якою слідує 1 або більше цифр, а потім цифри, розділені крапкою. У регулярному виразі є прапор i, так що регістр буде ігноруватися.
str = "For more information, see Chapter 3.4.5.1";re = / chapter (\ d + (\. \ d) *) / i;
found = str.match (re);
alert (found);
Скрипт видасть масив з збігів:
- Chapter 3.4.5.1 - повністю збіглася рядок
- 3.4.5.1 - перша дужка
- .1 - Внутрішня дужка
Наступний приклад демонструє використання прапорів глобального і регістронезавісімого пошуку з match. Будуть знайдені всі літери від А до Е і від а до е, кожна - в окремому елементі масиву.
var str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";var regexp = / [AE] / gi;
var matches = str.match (regexp);
document.write (matches);
// Matches = [ 'A', 'B', 'C', 'D', 'E', 'a', 'b', 'c', 'd', 'e']
Заміна, replace
Метод replace може заміняти входження регулярного вираження не тільки на рядок, а й на результат виконання функції. Його повний синтаксис - такий:
var newString = str.replace (regexp / substr, newSubStr / function)- regexp
- Об'єкт RegExp. Його входження будуть замінені на значення, яке поверне параметр номер 2
- substr
- Рядок, яка буде замінена на newSubStr.
- newSubStr
- Рядок, яка замінює підрядок з аргументу номер 1.
- function
- Функція, яка може бути викликана для генерації нової підрядка (щоб підставити її замість підрядка, отриманої з аргументу 1).
Метод replace не змінює рядок, на якій викликаний, а просто повертає нову, змінену рядок.
Щоб здійснити глобальну заміну, включіть в регулярний вираз прапор "g".
Якщо перший аргумент - рядок, то вона не перетвориться в регулярний вираз, так що, наприклад,
var ab = "ab" .replace ( "\\ s", "..") // = "ab"Виклик replace залишив рядок без зміни, т.к шукати не регулярний вираз \ s, а рядок "\ s".
Спецсимволи в рядку заміни
У рядку заміни можуть бути такі спецсимволи:
Pattern | Inserts |
$$ | Вставляє "$". |
$ & | Вставляє знайдену підрядок. |
$ ` | Вставляє частина рядка, яка передує знайденому входженню. |
$ ' | Вставляє частина рядка, яка йде після знайденого входження. |
$ N or $ nn | Де n або nn - десяткові цифри, вставляє підрядок входження, запомненную n -й вкладеної дужкою, якщо перший аргумент - об'єкт RegExp. |
Заміна через функцію
Якщо Ви вказуєте другим параметром функцію, то вона виконується при кожному збігу.
У функції можна динамічно генерувати і повертати рядок підстановки.
Перший параметр функції - знайдений підрядок. Якщо першим аргументом replace є об'єкт RegExp, то наступні n параметрів містять збіги з вкладених дужок. Останні два параметри - позиція в рядку, на якій відбулося збіг і сама рядок.
Наприклад, наступний виклик replace поверне XXzzzz - XX, zzzz.
function replacer (str, p1, p2, offset, s){
return str + "-" + p1 + "," + p2;
}
var newString = "XXzzzz" .replace (/ (X *) (z *) /, replacer)
Як бачите, тут дві дужки в регулярному виразі, і тому в функції два параметри p1, p2.
Якби були три дужки, то в функцію довелося б додати параметр p3.
Наступна функція замінює слова типу borderTop на border-top:
function styleHyphenFormat (propertyName){
function upperToHyphenLower (match)
{
return '-' + match.toLowerCase ();
}
return propertyName.replace (/ [AZ] /, upperToHyphenLower);
}
додатково
Для загального розуміння регулярних виразів можна почитати Статтю в wikipedia .
Більш докладно вони описані в книзі (англ.) Beginning Regular Expressions .
Коментарі
Коментуючи, пам'ятайте про те, що зміст і тон Вашого повідомлення можуть зачіпати почуття реальних людей, проявляйте повагу та толерантність до своїх співрозмовників навіть у тому випадку, якщо Ви не поділяєте їхню думку, Ваша поведінка за умов свободи висловлювань та анонімності, наданих інтернетом, змінює не тільки віртуальний, але й реальний світ. Всі коменти приховані з індексу, спам контролюється.