Мои мысли заключаются в том, что наличие отдельных модулей помогает с ясностью кода, а позже, если, по некоторым данным, эти модули вырастут до более чем 10 строк, я не буду так плохо относиться к их разделению.
blockquote>Это. Держи это так, как ты.
ECMAScript 2018 вводит группы захвата в регулярные выражения JavaScript.
Если вам нужно поддерживать старые браузеры, вы можете делать все с помощью обычных (нумерованных) групп захвата, которые вы можете сделать с именованными группами захвата, вам просто нужно отслеживать числа, которые могут быть громоздкими, если порядок захвата группы в вашем регулярном выражении изменяется.
Есть только два «структурных» преимущества названных групп захвата, о которых я могу думать:
(\ d)
на $ 10
. В JavaScript это будет работать (до тех пор, пока в вашем регулярном выражении будет менее 10 групп захвата), но Perl подумает, что вы ищете номер обратной ссылки 10
вместо номера 1
, а затем 0
. В Perl вы можете использовать $ {1} 0
в этом случае. Кроме этого, группы захвата называются «синтаксическим сахаром». Это помогает использовать группы захвата только тогда, когда они вам действительно понадобятся, и использовать во всех других случаях не захватывающие группы (?: ...)
.
Большая проблема (в мое мнение) с JavaScript заключается в том, что он не поддерживает многословные регулярные выражения, что облегчит создание понятных и сложных регулярных выражений.
Библиотека XRegExp Стив Левитана решает эти проблемы.
Вы можете использовать XRegExp , расширенную, расширяемую кросс-браузерную реализацию регулярных выражений, включая поддержку дополнительного синтаксиса, флагов и методов:
s
, чтобы совпадение точек со всеми символами ( aka dotall или singleline mode) и x
, для свободного пробега и комментариев (aka extended mode). В ES6 вы можете использовать деструктурирование массива, чтобы поймать ваши группы:
let text = '27 months '; пусть regex = / (\ d +) \ s * (days? | months? | years?) /; let [, count, unit] = text.match (regex) || []; // count === '27' // unit === 'months'
Обратите внимание:
пусть
пропускает первое значение результирующего массива, который представляет собой целую согласованную строку || []
после .match ()
предотвратит ошибку разрушения, если совпадений нет (поскольку .match ()
вернет null
]) String.prototype.match
возвращает массив с: всей совпадающей строкой в позиции 0, а затем с любыми группами после нее. Первая запятая говорит «пропустить элемент в положении 0»,
– bfred.it
31 July 2016 в 06:34
RegExp.prototype.exec
над String.prototype.match
в местах, где строка может быть null
или undefined
.
– Mike Hill
31 July 2017 в 15:29
Существует библиотека node.js, названная named-regexp , которую вы можете использовать в проектах node.js (в браузере путем упаковки библиотеки с помощью браузера или других сценариев упаковки). Тем не менее, библиотека не может использоваться с регулярными выражениями, которые содержат неименованные группы захвата.
Если вы считаете открывающие скобки для захвата в своем регулярном выражении, вы можете создать сопоставление между именованными группами захвата и нумерованными группами захвата в вашем регулярном выражении и может свободно смешиваться и сочетаться. Вам просто нужно удалить имена групп, прежде чем использовать регулярное выражение. Я написал три функции, которые демонстрируют это. См. Этот пояс: https://gist.github.com/gbirke/2cc2370135b665eee3ef
Именованные группы захвата могут быстро перейти на JavaScript. Предложение для него уже на этапе 3.
Группе захвата может быть присвоено имя с использованием синтаксиса (? ...) для любого имени идентификатора. Регулярное выражение для даты тогда может быть записано как / (? \ D {4}) - (? \ D {2}) - (? \ D {2}) / u. Каждое имя должно быть уникальным и следовать грамматике имени ECMAScript IdentifierName.
Доступ к именованным группам можно получить из свойств свойства групп результата регулярного выражения. Также создаются нумерованные ссылки на группы, как и для неименованных групп. Например:
let re = / (& lt; year & gt; \ d {4}) - (& lt; month & gt; \ d {2}) - (& lt; day & gt; \ д {2}) / U; let result = re.exec ('2015-01-02'); // result.groups.year === '2015'; // result.groups.month === '01'; // result.groups.day === '02'; // result [0] === '2015-01-02'; // result [1] === '2015'; // result [2] === '01'; // result [3] === '02';
Хотя вы не можете сделать это с помощью ванильного JavaScript, возможно, вы можете использовать некоторую функцию Array.prototype
, такую как Array.prototype.reduce
, чтобы превратить индексированные совпадения в именованные с помощью некоторой магии .
Очевидно, что следующее решение будет иметь следующие соответствия:
// @text Содержит текст для соответствия // @regex Объект регулярного выражения (fe /.+/) // @matchNames Массив литералов, где каждый элемент // является именем каждой групповой функции namedRegexMatch (text, regex, matchNames) {var matches = regex.exec (текст); return match.reduce (function (result, match, index) {if (index & gt; 0) // Эта подстановка требуется, потому что мы подсчитываем // сопоставляем индексы с 1, потому что 0 - весь результат согласованной строки [matchNames [index - 1]] = match; return result;}, {}); } var myString = «Привет, Алекс, я Джон»; var namedMatches = namedRegexMatch (myString, / Hello ([a-z] +), я ([a-z] +) / i, ["firstPersonName", "secondPersonName"]); alert (JSON.stringify (namedMatches));
var assocArray = Regex («hello alex, я dennis», «привет» ({hisName}. +), Я ({yourName}. +) & Quot;);
– Forivin
29 August 2015 в 16:46
RegExp
, добавив функцию в свой прототип.
– Mr. TA
16 February 2016 в 20:27
Другое возможное решение: создать объект, содержащий имена групп и индексы.
var regex = new RegExp ("(. *) (. *)"); var regexGroups = {FirstName: 1, LastName: 2};
Затем используйте объектные ключи для ссылки на группы:
var m = regex.exec («John Smith»); var f = m [regexGroups.FirstName];
Это улучшает читаемость / качество кода, используя результаты регулярного выражения, но не читаемость самого регулярного выражения.