As far as I know there is no such thing as named capturing groups in JavaScript. What is the alternative way to get similar functionality?
相关问题
- Is there a limit to how many levels you can nest i
- How to toggle on Order in ReactJS
- void before promise syntax
- Keeping track of variable instances
- Can php detect if javascript is on or not?
Another possible solution: create an object containing the group names and indexes.
Then, use the object keys to reference the groups:
This improves the readability/quality of the code using the results of the regex, but not the readability of the regex itself.
Naming captured groups provide one thing: less confusion with complex regular expressions.
It really depends on your use-case but maybe pretty-printing your regex could help.
Or you could try and define constants to refer to your captured groups.
Comments might then also help to show others who read your code, what you have done.
For the rest I must agree with Tims answer.
ECMAScript 2018 introduces named capturing groups into JavaScript regexes.
If you need to support older browsers, you can do everything with normal (numbered) capturing groups that you can do with named capturing groups, you just need to keep track of the numbers - which may be cumbersome if the order of capturing group in your regex changes.
There are only two "structural" advantages of named capturing groups I can think of:
In some regex flavors (.NET and JGSoft, as far as I know), you can use the same name for different groups in your regex (see here for an example where this matters). But most regex flavors do not support this functionality anyway.
If you need to refer to numbered capturing groups in a situation where they are surrounded by digits, you can get a problem. Let's say you want to add a zero to a digit and therefore want to replace
(\d)
with$10
. In JavaScript, this will work (as long as you have fewer than 10 capturing group in your regex), but Perl will think you're looking for backreference number10
instead of number1
, followed by a0
. In Perl, you can use${1}0
in this case.Other than that, named capturing groups are just "syntactic sugar". It helps to use capturing groups only when you really need them and to use non-capturing groups
(?:...)
in all other circumstances.The bigger problem (in my opinion) with JavaScript is that it does not support verbose regexes which would make the creation of readable, complex regular expressions a lot easier.
Steve Levithan's XRegExp library solves these problems.
There is a node.js library called named-regexp that you could use in your node.js projects (on in the browser by packaging the library with browserify or other packaging scripts). However, the library cannot be used with regular expressions that contain non-named capturing groups.
If you count the opening capturing braces in your regular expression you can create a mapping between named capturing groups and the numbered capturing groups in your regex and can mix and match freely. You just have to remove the group names before using the regex. I've written three functions that demonstrate that. See this gist: https://gist.github.com/gbirke/2cc2370135b665eee3ef
In ES6 you can use array destructuring to catch your groups:
Notice:
let
skips the first value of the resulting array, which is the whole matched string|| []
after.match()
will prevent a destructuring error when there are no matches (because.match()
will returnnull
)Update: It finally made it into JavaScript (ECMAScript 2018)!
Named capturing groups could make it into JavaScript very soon.
The proposal for it is at stage 3 already.
A capture group can be given a name inside angular brackets using the
(?<name>...)
syntax, for any identifier name. The regular expression for a date then can be written as/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/u
. Each name should be unique and follow the grammar for ECMAScript IdentifierName.Named groups can be accessed from properties of a groups property of the regular expression result. Numbered references to the groups are also created, just as for non-named groups. For example: