Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

regex-recursion

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

regex-recursion - npm Package Compare versions

Comparing version 4.3.0 to 5.0.0

2

dist/regex-recursion.min.js

@@ -1,2 +0,2 @@

var Regex;(Regex||={}).plugins=(()=>{var U=Object.defineProperty;var G=Object.getOwnPropertyDescriptor;var M=Object.getOwnPropertyNames;var W=Object.prototype.hasOwnProperty;var P=(e,t)=>{for(var n in t)U(e,n,{get:t[n],enumerable:!0})},_=(e,t,n,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of M(t))!W.call(e,o)&&o!==n&&U(e,o,{get:()=>t[o],enumerable:!(s=G(t,o))||s.enumerable});return e};var H=e=>_(U({},"__esModule",{value:!0}),e);var q={};P(q,{recursion:()=>z});var a=Object.freeze({DEFAULT:"DEFAULT",CHAR_CLASS:"CHAR_CLASS"});function A(e,t,n,s){let o=new RegExp(String.raw`${t}|(?<$skip>\[\^?|\\?.)`,"gsu"),c=[!1],r=0,u="";for(let i of e.matchAll(o)){let{0:l,groups:{$skip:p}}=i;if(!p&&(!s||s===a.DEFAULT==!r)){n instanceof Function?u+=n(i,{context:r?a.CHAR_CLASS:a.DEFAULT,negated:c[c.length-1]}):u+=n;continue}l[0]==="["?(r++,c.push(l[1]==="^")):l==="]"&&r&&(r--,c.pop()),u+=l}return u}function F(e,t,n,s){A(e,t,n,s)}function B(e,t,n=0,s){if(!new RegExp(t,"su").test(e))return null;let o=new RegExp(`${t}|(?<$skip>\\\\?.)`,"gsu");o.lastIndex=n;let c=0,r;for(;r=o.exec(e);){let{0:u,groups:{$skip:i}}=r;if(!i&&(!s||s===a.DEFAULT==!c))return r;u==="["?c++:u==="]"&&c&&c--,o.lastIndex==r.index&&o.lastIndex++}return null}function $(e,t,n){return!!B(e,t,0,n)}function L(e,t){let n=/\\?./gsu;n.lastIndex=t;let s=e.length,o=0,c=1,r;for(;r=n.exec(e);){let[u]=r;if(u==="[")o++;else if(o)u==="]"&&o--;else if(u==="(")c++;else if(u===")"&&(c--,!c)){s=r.index;break}}return e.slice(t,s)}var f=String.raw,j=f`\\g<(?<gRNameOrNum>[^>&]+)&R=(?<gRDepth>[^>]+)>`,x=f`\(\?R=(?<rDepth>[^\)]+)\)|${j}`,C=f`\(\?<(?![=!])(?<captureName>[^>]+)>`,w=new RegExp(f`${C}|${x}|\(\?|\\?.`,"gsu"),k="Cannot use multiple overlapping recursions";function z(e){if(!new RegExp(x,"su").test(e))return e;if($(e,f`\(\?\(DEFINE\)`,a.DEFAULT))throw new Error("DEFINE groups cannot be used with recursion");let t=$(e,f`\\[1-9]`,a.DEFAULT),n=new Map,s=[],o=!1,c=0,r=0,u;for(w.lastIndex=0;u=w.exec(e);){let{0:i,groups:{captureName:l,rDepth:p,gRNameOrNum:h,gRDepth:m}}=u;if(i==="[")c++;else if(c)i==="]"&&c--;else if(p){if(I(p),o)throw new Error(k);if(t)throw new Error("Numbered backrefs cannot be used with global recursion");let g=e.slice(0,u.index),d=e.slice(w.lastIndex);if($(d,x,a.DEFAULT))throw new Error(k);return T(g,d,+p,!1)}else if(h){I(m);let g=!1;for(let E of s)if(E.name===h||E.num===+h){if(g=!0,E.hasRecursedWithin)throw new Error(k);break}if(!g)throw new Error(f`Recursive \g cannot be used outside the referenced group "\g<${h}&R=${m}>"`);let d=n.get(h),R=L(e,d);if(t&&$(R,f`${C}|\((?!\?)`,a.DEFAULT))throw new Error("Numbered backrefs cannot be used with recursion of capturing groups");let D=e.slice(d,u.index),N=R.slice(D.length+i.length),b=T(D,N,+m,!0),O=e.slice(0,d),v=e.slice(d+R.length);e=`${O}${b}${v}`,w.lastIndex+=b.length-i.length-D.length-N.length,s.forEach(E=>E.hasRecursedWithin=!0),o=!0}else if(l)r++,n.set(String(r),w.lastIndex),n.set(l,w.lastIndex),s.push({num:r,name:l});else if(i.startsWith("(")){let g=i==="(";g&&(r++,n.set(String(r),w.lastIndex)),s.push(g?{num:r}:{})}else i===")"&&s.pop()}return e}function I(e){let t=`Max depth must be integer between 2 and 100; used ${e}`;if(!/^[1-9]\d*$/.test(e))throw new Error(t);if(e=+e,e<2||e>100)throw new Error(t)}function T(e,t,n,s){let o=new Set;s&&F(e+t,C,({groups:{captureName:r}})=>{o.add(r)},a.DEFAULT);let c=n-1;return`${e}${S(`(?:${e}`,c,s?o:null)}(?:)${S(`${t})`,c,s?o:null,"backward")}${t}`}function S(e,t,n,s="forward"){let c=u=>s==="backward"?t-u+2-1:u+2,r="";for(let u=0;u<t;u++){let i=c(u);r+=A(e,f`${C}|\\k<(?<backref>[^>]+)>`,({0:l,groups:{captureName:p,backref:h}})=>{if(h&&n&&!n.has(h))return l;let m=`_$${i}`;return p?`(?<${p}${m}>`:f`\k<${h}${m}>`},a.DEFAULT)}return r}return H(q);})();
var Regex;(Regex||={}).plugins=(()=>{var A=Object.defineProperty;var P=Object.getOwnPropertyDescriptor;var _=Object.getOwnPropertyNames;var H=Object.prototype.hasOwnProperty;var B=(e,t)=>{for(var r in t)A(e,r,{get:t[r],enumerable:!0})},j=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of _(t))!H.call(e,n)&&n!==r&&A(e,n,{get:()=>t[n],enumerable:!(o=P(t,n))||o.enumerable});return e};var z=e=>j(A({},"__esModule",{value:!0}),e);var K={};B(K,{recursion:()=>J});var f=Object.freeze({DEFAULT:"DEFAULT",CHAR_CLASS:"CHAR_CLASS"});function x(e,t,r,o){let n=new RegExp(String.raw`${t}|(?<$skip>\[\^?|\\?.)`,"gsu"),s=[!1],u=0,c="";for(let i of e.matchAll(n)){let{0:l,groups:{$skip:a}}=i;if(!a&&(!o||o===f.DEFAULT==!u)){r instanceof Function?c+=r(i,{context:u?f.CHAR_CLASS:f.DEFAULT,negated:s[s.length-1]}):c+=r;continue}l[0]==="["?(u++,s.push(l[1]==="^")):l==="]"&&u&&(u--,s.pop()),c+=l}return c}function I(e,t,r,o){x(e,t,r,o)}function q(e,t,r=0,o){if(!new RegExp(t,"su").test(e))return null;let n=new RegExp(`${t}|(?<$skip>\\\\?.)`,"gsu");n.lastIndex=r;let s=0,u;for(;u=n.exec(e);){let{0:c,groups:{$skip:i}}=u;if(!i&&(!o||o===f.DEFAULT==!s))return u;c==="["?s++:c==="]"&&s&&s--,n.lastIndex==u.index&&n.lastIndex++}return null}function C(e,t,r){return!!q(e,t,0,r)}function T(e,t){let r=/\\?./gsu;r.lastIndex=t;let o=e.length,n=0,s=1,u;for(;u=r.exec(e);){let[c]=u;if(c==="[")n++;else if(n)c==="]"&&n--;else if(c==="(")s++;else if(c===")"&&(s--,!s)){o=u.index;break}}return e.slice(t,o)}var h=String.raw,y=h`\\g<(?<gRNameOrNum>[^>&]+)&R=(?<gRDepth>[^>]+)>`,b=h`\(\?R=(?<rDepth>[^\)]+)\)|${y}`,R=h`\(\?<(?![=!])(?<captureName>[^>]+)>`,$=new RegExp(h`${R}|${b}|\(\?|\\?.`,"gsu"),N="Cannot use multiple overlapping recursions",S="$E$";function J(e,t){if(!new RegExp(b,"su").test(e))return e;if(C(e,h`\(\?\(DEFINE\)`,f.DEFAULT))throw new Error("DEFINE groups cannot be used with recursion");let r=!!t?.useEmulationGroups,o=C(e,h`\\[1-9]`,f.DEFAULT),n=new Map,s=[],u=!1,c=0,i=0,l;for($.lastIndex=0;l=$.exec(e);){let{0:a,groups:{captureName:m,rDepth:g,gRNameOrNum:p,gRDepth:D}}=l;if(a==="[")c++;else if(c)a==="]"&&c--;else if(g){if(O(g),u)throw new Error(N);if(o)throw new Error("Numbered backrefs cannot be used with global recursion");let d=e.slice(0,l.index),w=e.slice($.lastIndex);if(C(w,b,f.DEFAULT))throw new Error(N);return G(d,w,+g,!1,r)}else if(p){O(D);let d=!1;for(let E of s)if(E.name===p||E.num===+p){if(d=!0,E.hasRecursedWithin)throw new Error(N);break}if(!d)throw new Error(h`Recursive \g cannot be used outside the referenced group "\g<${p}&R=${D}>"`);let w=n.get(p),U=T(e,w);if(o&&C(U,h`${R}|\((?!\?)`,f.DEFAULT))throw new Error("Numbered backrefs cannot be used with recursion of capturing groups");let k=e.slice(w,l.index),F=U.slice(k.length+a.length),L=G(k,F,+D,!0,r),v=e.slice(0,w),W=e.slice(w+U.length);e=`${v}${L}${W}`,$.lastIndex+=L.length-a.length-k.length-F.length,s.forEach(E=>E.hasRecursedWithin=!0),u=!0}else if(m)i++,n.set(String(i),$.lastIndex),n.set(m,$.lastIndex),s.push({num:i,name:m});else if(a.startsWith("(")){let d=a==="(";d&&(i++,n.set(String(i),$.lastIndex)),s.push(d?{num:i}:{})}else a===")"&&s.pop()}return e}function O(e){let t=`Max depth must be integer between 2 and 100; used ${e}`;if(!/^[1-9]\d*$/.test(e))throw new Error(t);if(e=+e,e<2||e>100)throw new Error(t)}function G(e,t,r,o,n){let s=new Set;o&&I(e+t,R,({groups:{captureName:c}})=>{s.add(c)},f.DEFAULT);let u=r-1;return`${e}${M(`(?:${e}`,u,o?s:null,"forward",n)}(?:)${M(`${t})`,u,o?s:null,"backward",n)}${t}`}function M(e,t,r,o,n){let u=i=>o==="backward"?t-i+2-1:i+2,c="";for(let i=0;i<t;i++){let l=u(i);c+=x(e,h`${R}|\\k<(?<backref>[^>]+)>${n?h`|\((?!\?)`:""}`,({0:a,groups:{captureName:m,backref:g}})=>{if(g&&r&&!r.has(g))return a;if(a==="(")return`(${S}`;let p=`_$${l}`;return m?`(?<${m}${p}>${n?S:""}`:h`\k<${g}${p}>`},f.DEFAULT)}return c}return z(K);})();
//# sourceMappingURL=regex-recursion.min.js.map
{
"name": "regex-recursion",
"version": "4.3.0",
"version": "5.0.0",
"description": "Recursive matching plugin for Regex+",

@@ -16,2 +16,11 @@ "author": "Steven Levithan",

"types": "./types/index.d.ts",
"scripts": {
"bundle:global": "esbuild src/index.js --global-name=Regex.plugins --bundle --minify --sourcemap --outfile=dist/regex-recursion.min.js",
"types": "tsc src/index.js --rootDir src --declaration --allowJs --emitDeclarationOnly --outDir types",
"prebuild": "rm -rf dist/* types/*",
"build": "pnpm run bundle:global && pnpm run types",
"pretest": "pnpm run build",
"test": "jasmine",
"prepare": "pnpm test"
},
"files": [

@@ -36,14 +45,6 @@ "dist",

"esbuild": "^0.24.0",
"jasmine": "^5.4.0",
"jasmine": "^5.5.0",
"regex": "^5.0.2",
"typescript": "^5.7.2"
},
"scripts": {
"bundle:global": "esbuild src/index.js --global-name=Regex.plugins --bundle --minify --sourcemap --outfile=dist/regex-recursion.min.js",
"types": "tsc src/index.js --rootDir src --declaration --allowJs --emitDeclarationOnly --outDir types",
"prebuild": "rm -rf dist/* types/*",
"build": "pnpm run bundle:global && pnpm run types",
"pretest": "pnpm run build",
"test": "jasmine"
}
}
}

@@ -34,3 +34,3 @@ # regex-recursion

<script src="https://cdn.jsdelivr.net/npm/regex@5.0.2/dist/regex.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/regex-recursion@4.3.0/dist/regex-recursion.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/regex-recursion@5.0.0/dist/regex-recursion.min.js"></script>
<script>

@@ -37,0 +37,0 @@ const {regex} = Regex;

@@ -9,8 +9,14 @@ import {Context, forEachUnescaped, getGroupContents, hasUnescaped, replaceUnescaped} from 'regex-utilities';

const overlappingRecursionMsg = 'Cannot use multiple overlapping recursions';
// See <github.com/slevithan/regex/blob/main/src/subclass.js>
const emulationGroupMarker = '$E$';
/**
@param {string} expression
@param {{
flags?: string;
useEmulationGroups?: boolean;
}} [data]
@returns {string}
*/
export function recursion(expression) {
export function recursion(expression, data) {
// Keep the initial fail-check (which avoids unneeded processing) as fast as possible by testing

@@ -24,2 +30,3 @@ // without the accuracy improvement of using `hasUnescaped` with default `Context`

}
const useEmulationGroups = !!data?.useEmulationGroups;
const hasNumberedBackref = hasUnescaped(expression, r`\\[1-9]`, Context.DEFAULT);

@@ -62,3 +69,3 @@ const groupContentsStartPos = new Map();

// No need to parse further
return makeRecursive(pre, post, +rDepth, false);
return makeRecursive(pre, post, +rDepth, false, useEmulationGroups);
// `\g<name&R=N>`, `\g<number&R=N>`

@@ -90,3 +97,3 @@ } else if (gRNameOrNum) {

const groupContentsPost = groupContents.slice(groupContentsPre.length + m.length);
const expansion = makeRecursive(groupContentsPre, groupContentsPost, +gRDepth, true);
const expansion = makeRecursive(groupContentsPre, groupContentsPost, +gRDepth, true, useEmulationGroups);
const pre = expression.slice(0, startPos);

@@ -146,5 +153,6 @@ const post = expression.slice(startPos + groupContents.length);

@param {boolean} isSubpattern
@param {boolean} useEmulationGroups
@returns {string}
*/
function makeRecursive(pre, post, maxDepth, isSubpattern) {
function makeRecursive(pre, post, maxDepth, isSubpattern, useEmulationGroups) {
const namesInRecursed = new Set();

@@ -161,5 +169,5 @@ // Avoid this work if not needed

return `${pre}${
repeatWithDepth(`(?:${pre}`, reps, (isSubpattern ? namesInRecursed : null))
repeatWithDepth(`(?:${pre}`, reps, (isSubpattern ? namesInRecursed : null), 'forward', useEmulationGroups)
}(?:)${
repeatWithDepth(`${post})`, reps, (isSubpattern ? namesInRecursed : null), 'backward')
repeatWithDepth(`${post})`, reps, (isSubpattern ? namesInRecursed : null), 'backward', useEmulationGroups)
}${post}`;

@@ -172,6 +180,7 @@ }

@param {Set<string> | null} namesInRecursed
@param {'forward' | 'backward'} [direction]
@param {'forward' | 'backward'} direction
@param {boolean} useEmulationGroups
@returns {string}
*/
function repeatWithDepth(expression, reps, namesInRecursed, direction = 'forward') {
function repeatWithDepth(expression, reps, namesInRecursed, direction, useEmulationGroups) {
const startNum = 2;

@@ -184,3 +193,3 @@ const depthNum = i => direction === 'backward' ? reps - i + startNum - 1 : i + startNum;

expression,
r`${namedCapturingDelim}|\\k<(?<backref>[^>]+)>`,
r`${namedCapturingDelim}|\\k<(?<backref>[^>]+)>${useEmulationGroups ? r`|\((?!\?)` : ''}`,
({0: m, groups: {captureName, backref}}) => {

@@ -191,4 +200,9 @@ if (backref && namesInRecursed && !namesInRecursed.has(backref)) {

}
if (m === '(') {
return `(${emulationGroupMarker}`;
}
const suffix = `_$${captureNum}`;
return captureName ? `(?<${captureName}${suffix}>` : r`\k<${backref}${suffix}>`;
return captureName ?
`(?<${captureName}${suffix}>${useEmulationGroups ? emulationGroupMarker : ''}` :
r`\k<${backref}${suffix}>`;
},

@@ -195,0 +209,0 @@ Context.DEFAULT

/**
@param {string} expression
@param {{
flags?: string;
useEmulationGroups?: boolean;
}} [data]
@returns {string}
*/
export function recursion(expression: string): string;
export function recursion(expression: string, data?: {
flags?: string;
useEmulationGroups?: boolean;
}): string;

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc