Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. JavaScript

Регулярные выражения JavaScript: Поверх основ

by
Difficulty:IntermediateLength:MediumLanguages:

Russian (Pусский) translation by Anna Goorikova (you can also view the original English article)

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

Прочитав предыдущий урок, вы должны теперь хорошо понимать специальные символы, такие как обратная косая черта и последовательности символов, такие как \w или \W. Вот краткий обзор этих последовательностей символов:

  1. Вы можете использовать \d или \D для соответствия цифре или нецифровому символу в любой заданной строке соответственно. Цифры включают 0, 1, 2, 3, 4, 5, 6, 7, 8 и 9. Все остальные символы, кроме этих девяти, будут соответствовать \D.
  2. Вы можете использовать \w или \W для соответствия символу слова или не слова в любой заданной строке. Символы слова включают алфавиты, цифры и символ подчеркивания. Все остальное, например ₹,% и т. д., считается символом, отличным от слов.
  3. Вы можете использовать \s или \S для сопоставления символов пробела или символов не пробела в строке. Символы пробела будут включать пробел, табуляцию, фид и фид строки.

Вместо того, чтобы сопоставлять один символ за раз, вы можете использовать символ * для соответствия предыдущему выражению ноль или более раз. Символ + аналогично предыдущему выражению 1 или более раз.

Вы можете сопоставить шаблон любому конкретному количеству раз, добавив к нему {n, m}. Здесь n - минимальное количество раз, когда вы хотите его сопоставить, а m - максимальный предел. Если вы не укажете значение для m, предыдущее выражение будет соответствовать столько раз, сколько возможно.

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

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

Не жадные совпадения с использованием символа ?

Символ ? означает разные вещи в разных ситуациях.

При использовании в одиночку этот символ соответствует выражению, которое было до него 0 или 1 раз. В этом смысле он совпадает с {0,1}.

Вы также можете использовать ? сразу после других квантификаторов, таких как *, + и {}, чтобы соответствовать минимально возможному числу символов. Другими словами, это превратит эти жадные квантификаторы в не жадные. Это может быть немного трудно понять без живых примеров, поэтому давайте сначала посмотрим пример.

Рассмотрим следующее предложение:

Мне присвоен 17321HDGE как идентификатор пользователя, а моему другу назначен FHES193EK1.

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

Если мы используем выражение /\d+/g в примере, оно будет соответствовать одному или нескольким символам последовательных цифр. Из-за глобального флага будет три совпадения: 17321, 193 и 1.

Следует отметить, что 193 и 1 считаются разными совпадениями, поскольку они разделены EK.

В следующем примере показаны совпадения без использования каких-либо квантификаторов.

Теперь, добавив символ ? после \d+ вернет девять различных совпадений. В принципе, /\d+?/ превратит каждый символ цифры в отдельное совпадение. Почему это?

Это потому, что \d+ по определению должен соответствовать одной или нескольким цифрам. Так как символ ? должен соответствовать минимально возможному числу символов, он просто соответствует одной цифре за раз.

Не жадный ? квантификатор вернет 9 младших разрядов на этот раз. Для краткости я прокомментировал строку, которая записывает совпадения в консоль.

Возьмем еще один пример: регулярное выражение /\w+/ будет содержать совпадающие символы слов, если они не прерываются символом, отличным от слова, как пробел. В нашем случае он будет совпадать с целыми словами, разделенными пробелами, такими как assigned и 17321HDGE.

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

Теперь, изменив выражение на /\w+?/, вернется каждый символ слова как отдельное совпадение, и вы получите 68 совпадений.

Давайте рассмотрим последний пример, прежде чем двигаться дальше. Регулярное выражение /\w{4,}/ вернет все слова в нашем предложении, которые состоят из четырех символов или больше. Таким образом, соответствуют: have, been, assigned и 17321HDGE. Теперь, изменив его на /\w{4,}?/, вернется несколько совпадений из слов с более чем четырьмя символами. В нашем примере возвращаемые совпадения будут: have, been, assi, gned, 1732 и 1HGD. Символ E в конце 17321HDGE не является частью какого-либо совпадения, потому что он не может быть в группе любых четырех последовательных символов слов.

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

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

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

na naa nnaa nana naana

Для пояснения вы ищете жирный текст в виде совпадений: na naa nnaa (nana) naana. Часть в скобке должна быть сопоставлена как единое целое, так что она просто считается одним совпадением.

Почти каждый, кто только начинает работать с регулярными выражениями, будет использовать выражение /na{1,2}/ с целью получения ожидаемого результата. Они предполагают, что часть {1,2} должна совпадать с одним или двумя вхождениями n и a вместе. Однако, она фактически соответствует одному вхождению n, за которым следуют 1 или 2 вхождения символа a.

Я вывел жирным шрифтом совпадения, возвращаемые /na{1,2}/ для уточнения: na naa nnaa (na) (na) (naa) (na). Части в скобках являются отдельными совпадениями. Как вы можете видеть, мы не получаем желаемого результата, потому что {1,2} не рассматривает na как единую единицу, которая должна быть сопоставлена.

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

Если вы не хотите, чтобы JavaScript помнил совпадение, вам нужно добавить ?: перед группой символов, которую вы пытаетесь найти. В нашем случае окончательное выражение будет /(?:na){1,2}/. Группа na будет теперь учитываться как единица, и она не будет запоминаться. Я выделил финальные совпадения, возвращенные с этим выражением жирным шрифтом: na naa nnaa (nana) naana.

Следующий пример регистрирует все совпадения для консоли. Поскольку имеется 6 совпадений, общее количество вхождений равно 6.

Lookahead и обратный Lookahead

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

apples are yummy. We ate apples all day. Everyone who ate apples liked them.

В приведенном выше примере мы просто хотим, чтобы первое слово совпало. Любое другое вхождение этого слова не должно быть в совпадениях.

Один из способов добиться этого - использовать следующее регулярное выражение a(?=b). Слово, которое мы хотим сопоставить, - это а и слово, которое должно появиться после a - b. В нашем случае выражение будет /apples(?=\sare)/. Помните, что слово are не включено в это совпадение.

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

Очень похожая ситуация возникла бы, если бы вы решили сопоставить apples, только если бы за ним не последовал определенный набор символов. В таких случаях вам нужно заменить ?= на ?! в вашем регулярном выражении. Если мы ищем все случаи apples, за которыми не следовало бы are, мы будем использовать /apples(?!\sare)/ как наше регулярное выражение. Будет два успешных совпадения для нашего тестового предложения.

Кроме того, вам не нужно использовать два отдельных регулярных выражения, чтобы найти все совпадения, за которыми следует одно из двух заданных слов. Все, что вам нужно сделать, это добавить оператора pipe между этими словами, и готово. Например, если вы ищете все вхождения apples, за которыми следует are или were, вы должны использовать /apples(?!\sare|\swere)/ в качестве регулярного выражения.

Заключительные мысли

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

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

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.