Насколько я знаю, в JavaScript нет такой вещи, как именованные группы захвата. Какой альтернативный способ получить подобную функциональность?
javascript
regex
mmierins
источник
источник
Ответы:
ECMAScript 2018 вводит именованные группы захвата в регулярные выражения JavaScript.
Пример:
Если вам требуется поддержка старых браузеров, вы можете делать все с обычными (пронумерованными) группами захвата, что вы можете делать с именованными группами захвата, вам просто нужно отслеживать номера - что может быть громоздким, если порядок захвата группы в вашем изменения в регулярных выражениях.
Есть только два «структурных» преимущества именованных групп захвата, о которых я могу думать:
В некоторых вариантах регулярных выражений (насколько я знаю, .NET и JGSoft) вы можете использовать одно и то же имя для разных групп в своем регулярном выражении ( см. Пример, где это важно ). Но большинство разновидностей регулярных выражений в любом случае не поддерживают эту функцию.
Если вам нужно обратиться к пронумерованным группам захвата в ситуации, когда они окружены цифрами, вы можете получить проблему. Допустим, вы хотите добавить ноль к цифре и, следовательно, хотите заменить
(\d)
на$10
. В JavaScript это будет работать (до тех пор, пока в вашем регулярном выражении будет менее 10 групп захвата), но Perl будет думать, что вы ищете номер обратной ссылки10
вместо числа1
, за которым следует a0
. В Perl вы можете использовать${1}0
в этом случае.Кроме того, названные группы захвата являются просто «синтаксическим сахаром». Это помогает использовать группы захвата только тогда, когда они вам действительно нужны, и использовать группы без захвата
(?:...)
во всех других случаях.Большая проблема (на мой взгляд) с JavaScript состоит в том, что он не поддерживает подробные регулярные выражения, которые значительно упростили бы создание читаемых, сложных регулярных выражений.
Библиотека XRegExp Стива Левитана решает эти проблемы.
источник
Вы можете использовать XRegExp , расширенную, расширяемую, кросс-браузерную реализацию регулярных выражений, включая поддержку дополнительных синтаксиса, флагов и методов:
s
чтобы точка соответствовала всем символам (так называемый точечный или однострочный режим), иx
для свободного пробела и комментариев (также расширенный режим).источник
Другое возможное решение: создать объект, содержащий имена групп и индексы.
Затем используйте ключи объекта для ссылки на группы:
Это улучшает удобочитаемость / качество кода, используя результаты регулярного выражения, но не удобочитаемость самого регулярного выражения.
источник
В ES6 вы можете использовать деструктуризацию массива, чтобы поймать ваши группы:
Примечание:
let
пропускает первое значение результирующего массива, который является всей совпадающей строкой|| []
после.exec()
предотвратит ошибки деструктурирующие когда нет матчей (потому что.exec()
вернетсяnull
)источник
String.prototype.match
возвращает массив с: всей совпавшей строкой в позиции 0, затем любыми группами после этого. Первая запятая гласит «пропустить элемент в позиции 0»RegExp.prototype.exec
за кадромString.prototype.match
в тех местах , где строка может бытьnull
илиundefined
.Обновление: оно наконец-то превратилось в JavaScript (ECMAScript 2018)!
Именованные группы захвата могут очень скоро превратиться в JavaScript.
Предложение об этом уже на третьем этапе.
Группе захвата может быть присвоено имя в угловых скобках с использованием
(?<name>...)
синтаксиса для любого имени идентификатора. Регулярное выражение для даты тогда может быть записано как/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/u
. Каждое имя должно быть уникальным и следовать грамматике для ECMAScript IdentifierName .Именованные группы можно получить из свойств свойства groups результата регулярного выражения. Пронумерованные ссылки на группы также создаются, как и для неназванных групп. Например:
источник
let {year, month, day} = ((result) => ((result) ? result.groups : {}))(re.exec('2015-01-02'));
Наименование захваченных групп дает одно: меньше путаницы со сложными регулярными выражениями.
Это действительно зависит от вашего варианта использования, но, возможно, симпатичная печать вашего регулярного выражения может помочь.
Или вы можете попытаться определить константы для ссылок на ваши захваченные группы.
Комментарии могут также помочь показать другим, кто читает ваш код, что вы сделали.
В остальном я должен согласиться с ответом Тимса.
источник
Существует библиотека node.js с именем named-regexp, которую вы можете использовать в своих проектах node.js (в браузере, упаковав библиотеку browserify или другими пакетными скриптами). Однако эту библиотеку нельзя использовать с регулярными выражениями, которые содержат неназванные группы захвата.
Если вы подсчитываете вводные скобки в своем регулярном выражении, вы можете создать отображение между именованными группами захвата и пронумерованными группами захвата в своем регулярном выражении и можете свободно смешивать и сопоставлять. Вам просто нужно удалить имена групп перед использованием регулярных выражений. Я написал три функции, которые демонстрируют это. Посмотреть эту суть: https://gist.github.com/gbirke/2cc2370135b665eee3ef
источник
Как сказал Тим Пицкер, ECMAScript 2018 вводит именованные группы захвата в регулярные выражения JavaScript. Но что я не нашел в приведенных выше ответах, так это как использовать именованную захваченную группу в самом регулярном выражении.
Вы можете использовать захваченное с именем группы с этим синтаксисом:
\k<name>
. напримери, как сказал Форивин, вы можете использовать захваченную группу в результате объекта следующим образом:
источник
Хотя вы не можете сделать это с помощью обычного JavaScript, возможно, вы можете использовать какую-то
Array.prototype
функцию, например,Array.prototype.reduce
чтобы превратить индексированные совпадения в именованные, используя некоторую магию .Очевидно, что следующему решению потребуется, чтобы совпадения происходили по порядку:
источник
var assocArray = Regex("hello alex, I am dennis", "hello ({hisName}.+), I am ({yourName}.+)");
RegExp
объект, добавив функцию к его прототипу.У вас нет ECMAScript 2018?
Моя цель состояла в том, чтобы сделать его максимально похожим на то, к чему мы привыкли с именованными группами. В то время как в ECMAScript 2018 вы можете поместить
?<groupname>
внутри группы, чтобы указать именованную группу, в моем решении для старого javascript вы можете поместить(?!=<groupname>)
в группу, чтобы сделать то же самое. Так что это дополнительный набор скобок и дополнительный!=
. Довольно близко!Я обернул все это в функцию прототипа строки
Характеристики
инструкции
(?!={groupname})
внутри каждой группы, которую вы хотите назвать()
, поместив?:
в начале этой группы. Они не будут названы.arrays.js
использование
результат о
источник