Skip to content

Commit

Permalink
Subroutines: Avoid adding captures if no backrefs (part 2)
Browse files Browse the repository at this point in the history
  • Loading branch information
slevithan committed Jul 22, 2024
1 parent 9981716 commit 8753824
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 5 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ See the next section on definition groups for another way to do this.
- Subroutines can appear before the groups they reference, as shown in examples above.
- If there are [duplicate capture names](https://github.com/tc39/proposal-duplicate-named-capturing-groups), subroutines refer to the first instance of the given group (matching the behavior of PCRE and Perl).
- Although subroutines can be chained to any depth, a descriptive error is thrown if they're used recursively. Support for recursion can be added via an extension (see [*Recursion*](#recursion)).
- Like backreferences, subroutines can't be used from *within* character classes.
- As with all new syntax in `regex`, subroutines are applied after interpolation, giving them maximal flexibility.
</details>

Expand Down
11 changes: 6 additions & 5 deletions src/subroutines.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,12 @@ function processSubroutines(expression, namedGroups) {
if (openSubroutinesMap.size) {
// Named capturing group
if (m !== '(') {
// Replace named with unnamed capture. Subroutines shouldn't create new captures, but
// it can't be helped since we need any backrefs to this named capture to work. Given
// that implicit flag n prevents unnamed capture and requires you to rely on named
// backrefs and `groups`, this essentially accomplishes not creating a capture
result = spliceStr(result, index, m, '(');
// Replace named with unnamed capture. Subroutines ideally wouldn't create any new
// captures, but it can't be helped since we need any backrefs to this named capture to
// work. Given that flag n prevents unnamed capture and thereby requires you to rely on
// named backrefs and `groups`, switching to unnamed essentially accomplishes not
// creating a capture. Fully avoid capturing if there are no backrefs in the expression
result = spliceStr(result, index, m, '(' + (hasBackrefs ? '' : '?:'));
token.lastIndex -= m.length;
}
backrefIncrements.push(lastOf(backrefIncrements) + subroutine.numCaptures);
Expand Down

0 comments on commit 8753824

Please sign in to comment.