Skip to content

Latest commit

 

History

History
190 lines (118 loc) · 9.64 KB

File metadata and controls

190 lines (118 loc) · 9.64 KB

Символьные классы

Рассмотрим практическую задачу - у нас есть номер телефона вида "+7(903)-123-45-67", и нам нужно превратить его в строку только из чисел: 79031234567.

Для этого мы можем найти и удалить всё, что не является числом. С этим нам помогут символьные классы.

Символьный класс - это специальное обозначение, которое соответствует любому символу из определённого набора.

Для начала давайте рассмотрим класс "цифра". Он обозначается как pattern:\d и в регулярном выражении соответствует "любой одной цифре".

Например, давайте найдём первую цифру в номере телефона:

let str = "+7(903)-123-45-67";

let regexp = /\d/;

alert( str.match(regexp) ); // 7

Без флага pattern:g регулярное выражение ищет только первое совпадение, то есть первую цифру pattern:\d.

Давайте добавим флаг pattern:g, чтобы найти все цифры:

let str = "+7(903)-123-45-67";

let regexp = /\d/g;

alert( str.match(regexp) ); // массив совпадений: 7,9,0,3,1,2,3,4,5,6,7

// и можно сделать из них уже чисто цифровой номер телефона
alert( str.match(regexp).join('') ); // 79031234567

Это был символьный класс для цифр. Есть и другие символьные классы.

Наиболее используемые:

pattern:\d ("d" от английского "digit" означает "цифра") : Цифра: символ от 0 до 9.

pattern:\s ("s": от английского "space" – "пробел") : Пробельные символы: включает в себя символ пробела, табуляции \t, перевода строки \n и некоторые другие редкие пробельные символы, обозначаемые как \v, \f и \r.

pattern:\w ("w": от английского "word" – "слово") : Символ "слова", а точнее – буква латинского алфавита, цифра или подчёркивание _. Нелатинские буквы не являются частью класса pattern:\w, то есть буква русского алфавита не подходит.

Для примера, pattern:\d\s\w обозначает "цифру", за которой идёт пробельный символ, а затем символ слова, например match:1 a.

Регулярное выражение может содержать как обычные символы, так и символьные классы.

Например, pattern:CSS\d соответствует строке match:CSS с цифрой после неё:

let str = "Есть ли стандарт CSS4?";
let regexp = /CSS\d/

alert( str.match(regexp) ); // CSS4

Также мы можем использовать несколько символьных классов:

alert( "I love HTML5!".match(/\s\w\w\w\w\d/) ); // ' HTML5'

Соответствие (каждому символьному классу соответствует один символ результата):

Обратные символьные классы

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

"Обратный" означает, что он соответствует всем другим символам, например:

pattern:\D : Не цифра: любой символ, кроме pattern:\d, например буква.

pattern:\S : Не пробел: любой символ, кроме pattern:\s, например буква.

pattern:\W : Любой символ, кроме pattern:\w, то есть не буква из латиницы, не знак подчёркивания и не цифра. В частности, русские буквы принадлежат этому классу.

Мы уже видели, как сделать чисто цифровой номер из строки вида subject:+7(903)-123-45-67: найти все цифры и соединить их.

let str = "+7(903)-123-45-67";

alert( str.match(/\d/g).join('') ); // 79031234567

Альтернативный, более короткий путь - найти нецифровые символы pattern:\D и удалить их из строки:

let str = "+7(903)-123-45-67";

alert( str.replace(/\D/g, "") ); // 79031234567

Точка - это любой символ

Точка pattern:. - это специальный символьный класс, который соответствует "любому символу, кроме новой строки".

Для примера:

alert( "Ю".match(/./) ); // Ю

Или в середине регулярного выражения:

let regexp = /CS.4/;

alert( "CSS4".match(regexp) ); // CSS4
alert( "CS-4".match(regexp) ); // CS-4
alert( "CS 4".match(regexp) ); // CS 4 (пробел тоже является символом)

Обратите внимание, что точка означает "любой символ", но не "отсутствие символа". Там должен быть какой-либо символ, чтобы соответствовать условию поиска:

alert( "CS4".match(/CS.4/) ); // null, нет совпадений, потому что нет символа для точки

Точка как буквально любой символ, с флагом "s"

Обычно точка не соответствует символу новой строки \n.

То есть регулярное выражение pattern:A.B будет искать символ match:A и затем match:B, с любым символом между ними, кроме перевода строки \n:

alert( "A\nB".match(/A.B/) ); // null (нет совпадения)

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

Как раз для этого нужен флаг pattern:s. Если регулярное выражение имеет его, то точка pattern:. соответствует буквально любому символу:

alert( "A\nB".match(/A.B/s) ); // A\nB (совпадение!)
Обычно мы уделяем мало внимания пробелам. Для нас строки `subject:1-5` и `subject: 1 - 5` практически идентичны.

Но если регулярное выражение не учитывает пробелы, оно может не сработать.

Давайте попробуем найти цифры, разделённые дефисом:

```js run
alert( "1 - 5".match(/\d-\d/) ); // null, нет совпадения!
```

Исправим это, добавив пробелы в регулярное выражение `pattern:\d - \d`:

```js run
alert( "1 - 5".match(/\d - \d/) ); // 1 - 5, теперь работает
// или можно использовать класс \s:
alert( "1 - 5".match(/\d\s-\s\d/) ); // 1 - 5, тоже работает
```

**Пробел - это символ. Такой же важный, как любой другой.**

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

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

Итого

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

  • pattern:\d -- цифры.
  • pattern:\D -- не цифры.
  • pattern:\s -- пробельные символы, табы, новые строки.
  • pattern:\S -- все, кроме pattern:\s.
  • pattern:\w -- латиница, цифры, подчёркивание _.
  • pattern:\W -- все, кроме pattern:\w.
  • pattern:. -- любой символ, если с флагом регулярного выражения pattern:s, в противном случае любой символ, кроме перевода строки \n.

...Но это не всё!

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

Можно искать, в том числе, и по этим свойствам. Для этого нужен флаг pattern:u, который мы рассмотрим в следующей главе.