Last active

Embed URL

HTTPS clone URL

SSH clone URL

You can clone with HTTPS or SSH.

Download Gist

Generating a regular expression to match valid JavaScript identifiers (like https://mathiasbynens.be/demo/javascript-identifier-regex) in Node.js

View .gitignore
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
// Note: run `npm install` first!
 
var regenerate = require('regenerate');
var template = require('lodash.template');
 
// Which Unicode version should be used?
var version = '8.0.0';
 
// Set up a shorthand function to import Unicode data.
var get = function(what) {
return require('unicode-' + version + '/' + what + '/code-points');
};
 
// Get the Unicode categories needed to construct the ES5 regex.
var Lu = get('categories/Lu');
var Ll = get('categories/Ll');
var Lt = get('categories/Lt');
var Lm = get('categories/Lm');
var Lo = get('categories/Lo');
var Nl = get('categories/Nl');
var Mn = get('categories/Mn');
var Mc = get('categories/Mc');
var Nd = get('categories/Nd');
var Pc = get('categories/Pc');
 
// Get the Unicode properties needed to construct the ES6 regex.
var ID_Start = get('properties/ID_Start');
var ID_Continue = get('properties/ID_Continue');
var Other_ID_Start = get('properties/Other_ID_Start');
 
var compileRegex = template('/^(?!(?:<%= reservedWords %>)$)' +
'(?:<%= identifierStart %>)(?:<%= identifierPart %>)*$/');
 
var generateES5Regex = function() { // ES 5.1
// https://mathiasbynens.be/notes/javascript-identifiers#valid-identifier-names
var identifierStart = regenerate('$', '_')
.add(Lu, Ll, Lt, Lm, Lo, Nl)
.removeRange(0x010000, 0x10FFFF); // remove astral symbols
var identifierPart = identifierStart.clone()
.add('\u200C', '\u200D', Mn, Mc, Nd, Pc)
.removeRange(0x010000, 0x10FFFF); // remove astral symbols
 
var reservedWords = [
// https://mathiasbynens.be/notes/reserved-keywords#ecmascript-5
'do', 'if', 'in', 'for', 'let', 'new', 'try', 'var', 'case', 'else',
'enum', 'eval', 'null', 'this', 'true', 'void', 'with', 'break', 'catch',
'class', 'const', 'false', 'super', 'throw', 'while', 'yield', 'delete',
'export', 'import', 'public', 'return', 'static', 'switch', 'typeof',
'default', 'extends', 'finally', 'package', 'private', 'continue',
'debugger', 'function', 'arguments', 'interface', 'protected',
'implements', 'instanceof',
// These aren’t strictly reserved words, but they kind of behave as if
// they were.
//'NaN', 'Infinity', 'undefined'
];
 
var regex = compileRegex({
'reservedWords': reservedWords.join('|'),
'identifierStart': identifierStart.toString(),
'identifierPart': identifierPart.toString()
});
return regex;
};
 
var generateES6Regex = function() {
// http://ecma-international.org/ecma-262/6.0/#sec-identifier-names-static-semantics-early-errors
// http://unicode.org/reports/tr31/#Default_Identifier_Syntax
// https://bugs.ecmascript.org/show_bug.cgi?id=2717#c0
var identifierStart = regenerate(ID_Start)
// Note: this already includes `Other_ID_Start`. http://git.io/wRCAfQ
.add(
'$',
'_'
);
var identifierPart = regenerate(ID_Continue)
// Note: `ID_Continue` already includes `Other_ID_Continue`. http://git.io/wRCAfQ
.add(Other_ID_Start)
.add(
'$',
'_',
'\u200C',
'\u200D'
);
 
var reservedWords = [
// https://mathiasbynens.be/notes/reserved-keywords#ecmascript-6
'do', 'if', 'in', 'for', 'let', 'new', 'try', 'var', 'case', 'else',
'enum', 'eval', 'null', 'this', 'true', 'void', 'with', 'await', 'break',
'catch', 'class', 'const', 'false', 'super', 'throw', 'while', 'yield',
'delete', 'export', 'import', 'public', 'return', 'static', 'switch',
'typeof', 'default', 'extends', 'finally', 'package', 'private',
'continue', 'debugger', 'function', 'arguments', 'interface', 'protected',
'implements', 'instanceof',
// These aren’t strictly reserved words, but they kind of behave as if
// they were.
//'NaN', 'Infinity', 'undefined'
];
 
var regex = compileRegex({
'reservedWords': reservedWords.join('|'),
'identifierStart': identifierStart.toString(),
'identifierPart': identifierPart.toString()
});
return regex;
};
 
console.log('// ECMAScript 5.1:\n')
console.log(generateES5Regex());
console.log('\n// ECMAScript 6:\n');
console.log(generateES6Regex());
View .gitignore
1 2 3 4 5 6 7 8
{
"private": true,
"dependencies": {
"lodash.template": "^3.6.1",
"regenerate": "^1.2.1",
"unicode-8.0.0": "^0.1.5"
}
}

This is the Node.js version of https://mathiasbynens.be/demo/javascript-identifier-regex.

Patches based on this gist:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.