Skip to content

Instantly share code, notes, and snippets.

@jordanbtucker
Last active March 31, 2016 18:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jordanbtucker/c5a860338a6c4e3577ef to your computer and use it in GitHub Desktop.
Save jordanbtucker/c5a860338a6c4e3577ef to your computer and use it in GitHub Desktop.
Different ways to test for identifiers in JavaScript

Different ways to test for identifiers in JavaScript

Each file in this Gist is a different method of checking whether a string is an ECMAScript 5.1 identifier.

Each method consists of four data structures representing classes of Unicode characters. There are two main categories of data structures: letters and other characters. Identifiers must start with a character from the letters category (also $ or _), then they may optionally be followed by zero or more characters from the others category.

Each category has two sub-categories: singles and ranges. The singles are characters that only have zero or one adjacent characters within the same class according to their code point values. Every pair of characters in the ranges category compose a set of consecutive characters within the same class according to their code point values.

So, if composed to regular expressions, the categories resemble this:

letters > singles = /[ªµºˬ   ... ]/
letters > ranges  = /[A-Za-z ... ]/

The Array method represents each category as an array of code point values, which are converted to characters and compared to each character in the test string. This method is the smallest in byte size, weighing in at ~5.7KB. In testing it was the second fastest method, ~36% slower than the fastest.

The Strings method represents each category as a string of characters, which are compared to each character in the test string. This method is the second smallest in byte size, weighing in at ~6KB. In testing it was the slowest method, ~95% slower than the fastest.

The Regexes method represents each category as a regular expression, which is used to test each character in the test string. This method is the largest in byte size, weighing in at ~6.1KB. In testing it was the fastest method. The Regexes method could also be refactored to use only two regular expressions instead of four. It could actually be one very long regular expression.

var unicode = {
letters: {
singles: [
170,181,186,748,750,886,887,902,908,1369,1646,1647,1749,1765,1766,1774,
1775,1791,1808,1969,2036,2037,2042,2365,2384,2417,2418,2447,2448,2482,
2493,2510,2524,2525,2544,2545,2575,2576,2610,2611,2613,2614,2616,2617,
2654,2738,2739,2749,2768,2784,2785,2831,2832,2866,2867,2877,2908,2909,
2929,2947,2969,2970,2972,2974,2975,2979,2980,3024,3133,3160,3161,3168,
3169,3261,3294,3296,3297,3389,3424,3425,3517,3634,3635,3713,3714,3716,
3719,3720,3722,3725,3749,3751,3754,3755,3762,3763,3773,3782,3804,3805,
3840,4159,4193,4197,4198,4238,4348,4696,4800,6103,6108,6314,7086,7087,
8025,8027,8029,8126,8305,8319,8450,8455,8469,8484,8486,8488,8526,11631,
11823,13312,19893,19968,40899,42508,42891,42892,65392,65438,65439
],
ranges: [
65,90,97,122,192,214,216,246,248,705,710,721,736,740,880,884,890,893,904,
906,910,929,931,1013,1015,1153,1162,1315,1329,1366,1377,1415,1488,1514,
1520,1522,1569,1610,1649,1747,1786,1788,1810,1839,1869,1957,1994,2026,
2308,2361,2392,2401,2427,2431,2437,2444,2451,2472,2474,2480,2486,2489,
2527,2529,2565,2570,2579,2600,2602,2608,2649,2652,2674,2676,2693,2701,
2703,2705,2707,2728,2730,2736,2741,2745,2821,2828,2835,2856,2858,2864,
2869,2873,2911,2913,2949,2954,2958,2960,2962,2965,2984,2986,2990,3001,
3077,3084,3086,3088,3090,3112,3114,3123,3125,3129,3205,3212,3214,3216,
3218,3240,3242,3251,3253,3257,3333,3340,3342,3344,3346,3368,3370,3385,
3450,3455,3461,3478,3482,3505,3507,3515,3520,3526,3585,3632,3648,3654,
3732,3735,3737,3743,3745,3747,3757,3760,3776,3780,3904,3911,3913,3948,
3976,3979,4096,4138,4176,4181,4186,4189,4206,4208,4213,4225,4256,4293,
4304,4346,4352,4441,4447,4514,4520,4601,4608,4680,4682,4685,4688,4694,
4698,4701,4704,4744,4746,4749,4752,4784,4786,4789,4792,4798,4802,4805,
4808,4822,4824,4880,4882,4885,4888,4954,4992,5007,5024,5108,5121,5740,
5743,5750,5761,5786,5792,5866,5870,5872,5888,5900,5902,5905,5920,5937,
5952,5969,5984,5996,5998,6000,6016,6067,6176,6263,6272,6312,6400,6428,
6480,6509,6512,6516,6528,6569,6593,6599,6656,6678,6917,6963,6981,6987,
7043,7072,7168,7203,7245,7247,7258,7293,7424,7615,7680,7957,7960,7965,
7968,8005,8008,8013,8016,8023,8031,8061,8064,8116,8118,8124,8130,8132,
8134,8140,8144,8147,8150,8155,8160,8172,8178,8180,8182,8187,8336,8340,
8458,8467,8473,8477,8490,8493,8495,8505,8508,8511,8517,8521,8544,8584,
11264,11310,11312,11358,11360,11375,11377,11389,11392,11492,11520,11557,
11568,11621,11648,11670,11680,11686,11688,11694,11696,11702,11704,11710,
11712,11718,11720,11726,11728,11734,11736,11742,12293,12295,12321,12329,
12337,12341,12344,12348,12353,12438,12445,12447,12449,12538,12540,12543,
12549,12589,12593,12686,12704,12727,12784,12799,40960,41391,42560,42591,
42594,42605,42623,42647,42775,42783,42786,42888,64256,64262,64275,64279,
65313,65338,65345,65370
]
},
others: {
singles: [
95,1471,1473,1474,1476,1477,1479,1648,1767,1768,1809,2305,2306,2364,2381,
2402,2403,2433,2492,2509,2530,2531,2561,2562,2620,2625,2626,2631,2632,
2641,2677,2689,2690,2748,2759,2760,2765,2786,2787,2817,2876,2879,2893,
2902,2914,2915,2946,3008,3021,3157,3158,3170,3171,3260,3263,3270,3276,
3277,3298,3299,3405,3426,3427,3530,3542,3633,3761,3771,3772,3864,3865,
3893,3895,3897,3974,3975,4038,4153,4154,4157,4158,4184,4185,4226,4229,
4230,4237,4959,5970,5971,6002,6003,6086,6109,6313,6439,6440,6450,6679,
6680,6964,6972,6978,7040,7041,7080,7081,7222,7223,7678,7679,8255,8256,
8276,8417,12441,12442,42607,42620,42621,43010,43014,43019,43045,43046,
43204,43569,43570,43573,43574,43587,43596,64286,65075,65076,65343
],
ranges: [
48,57,768,879,1155,1159,1425,1469,1552,1562,1611,1630,1632,1641,1750,1756,
1759,1764,1770,1773,1776,1785,1840,1866,1958,1968,1984,1993,2027,2035,
2369,2376,2385,2388,2406,2415,2497,2500,2534,2543,2635,2637,2662,2673,
2753,2757,2790,2799,2881,2884,2918,2927,3046,3055,3134,3136,3142,3144,
3146,3149,3174,3183,3302,3311,3393,3396,3430,3439,3538,3540,3636,3642,
3655,3662,3664,3673,3764,3769,3784,3789,3792,3801,3872,3881,3953,3966,
3968,3972,3984,3991,3993,4028,4141,4144,4146,4151,4160,4169,4190,4192,
4209,4212,4240,4249,5906,5908,5938,5940,6071,6077,6089,6099,6112,6121,
6155,6157,6160,6169,6432,6434,6457,6459,6470,6479,6608,6617,6912,6915,
6966,6970,6992,7001,7019,7027,7074,7077,7088,7097,7212,7219,7232,7241,
7248,7257,7616,7654,8400,8412,8421,8432,11744,11775,12330,12335,42528,
42537,43216,43225,43264,43273,43302,43309,43335,43345,43561,43566,43600,
43609,65024,65039,65056,65062,65101,65103,65296,65305
]
}
};
var isInCategory = function(c, category) {
var r = category.ranges;
for(var i = 0; i < r.length - 1; i += 2)
if(c >= r[i] && c <= r[i + 1])
return true;
if(category.singles.indexOf(c) >= 0)
return true;
return false;
};
var isLetter = function(c) {
return isInCategory(c, unicode.letters);
};
var isOther = function(c) {
return isInCategory(c, unicode.others);
};
var isIdentifierStart = function(c) {
return c === "$" || c === '_' || isLetter(c.charCodeAt(0));
};
var isIdentifierChar = function(c) {
return isIdentifierStart(c) || isOther(c.charCodeAt(0));
};
var isIdentifier = function(s) {
if(!s.length)
return false;
if(!isIdentifierStart(s[0]))
return false;
for(var i = 1; i < s.length; i++)
if(!isIdentifierChar(s[i]))
return false;
return true;
};
module.exports = isIdentifier;
var unicode = {
letters: {
singles: /[\xaa\xb5\xba\u02ec\u02ee\u0376\u0377\u0386\u038c\u0559\u066e\u066f\u06d5\u06e5\u06e6\u06ee\u06ef\u06ff\u0710\u07b1\u07f4\u07f5\u07fa\u093d\u0950\u0971\u0972\u098f\u0990\u09b2\u09bd\u09ce\u09dc\u09dd\u09f0\u09f1\u0a0f\u0a10\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a5e\u0ab2\u0ab3\u0abd\u0ad0\u0ae0\u0ae1\u0b0f\u0b10\u0b32\u0b33\u0b3d\u0b5c\u0b5d\u0b71\u0b83\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0bd0\u0c3d\u0c58\u0c59\u0c60\u0c61\u0cbd\u0cde\u0ce0\u0ce1\u0d3d\u0d60\u0d61\u0dbd\u0e32\u0e33\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0ea5\u0ea7\u0eaa\u0eab\u0eb2\u0eb3\u0ebd\u0ec6\u0edc\u0edd\u0f00\u103f\u1061\u1065\u1066\u108e\u10fc\u1258\u12c0\u17d7\u17dc\u18aa\u1bae\u1baf\u1f59\u1f5b\u1f5d\u1fbe\u2071\u207f\u2102\u2107\u2115\u2124\u2126\u2128\u214e\u2d6f\u2e2f\u3400\u4db5\u4e00\u9fc3\ua60c\ua78b\ua78c\uff70\uff9e\uff9f]/,
ranges: /[\x41-\x5a\x61-\x7a\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u0370-\u0374\u037a-\u037d\u0388-\u038a\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0523\u0531-\u0556\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0621-\u064a\u0671-\u06d3\u06fa-\u06fc\u0712-\u072f\u074d-\u07a5\u07ca-\u07ea\u0904-\u0939\u0958-\u0961\u097b-\u097f\u0985-\u098c\u0993-\u09a8\u09aa-\u09b0\u09b6-\u09b9\u09df-\u09e1\u0a05-\u0a0a\u0a13-\u0a28\u0a2a-\u0a30\u0a59-\u0a5c\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab5-\u0ab9\u0b05-\u0b0c\u0b13-\u0b28\u0b2a-\u0b30\u0b35-\u0b39\u0b5f-\u0b61\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0ba8-\u0baa\u0bae-\u0bb9\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d28\u0d2a-\u0d39\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dc0-\u0dc6\u0e01-\u0e30\u0e40-\u0e46\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ead-\u0eb0\u0ec0-\u0ec4\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8b\u1000-\u102a\u1050-\u1055\u105a-\u105d\u106e-\u1070\u1075-\u1081\u10a0-\u10c5\u10d0-\u10fa\u1100-\u1159\u115f-\u11a2\u11a8-\u11f9\u1200-\u1248\u124a-\u124d\u1250-\u1256\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u1676\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u1820-\u1877\u1880-\u18a8\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19a9\u19c1-\u19c7\u1a00-\u1a16\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffb\u2090-\u2094\u210a-\u2113\u2119-\u211d\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2c6f\u2c71-\u2c7d\u2c80-\u2ce4\u2d00-\u2d25\u2d30-\u2d65\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31b7\u31f0-\u31ff\ua000-\ua1af\ua640-\ua65f\ua662-\ua66d\ua67f-\ua697\ua717-\ua71f\ua722-\ua788\ufb00-\ufb06\ufb13-\ufb17\uff21-\uff3a\uff41-\uff5a]/,
},
others: {
singles: /[\x5f\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0670\u06e7\u06e8\u0711\u0901\u0902\u093c\u094d\u0962\u0963\u0981\u09bc\u09cd\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a51\u0a75\u0a81\u0a82\u0abc\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3f\u0b4d\u0b56\u0b62\u0b63\u0b82\u0bc0\u0bcd\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc6\u0ccc\u0ccd\u0ce2\u0ce3\u0d4d\u0d62\u0d63\u0dca\u0dd6\u0e31\u0eb1\u0ebb\u0ebc\u0f18\u0f19\u0f35\u0f37\u0f39\u0f86\u0f87\u0fc6\u1039\u103a\u103d\u103e\u1058\u1059\u1082\u1085\u1086\u108d\u135f\u1752\u1753\u1772\u1773\u17c6\u17dd\u18a9\u1927\u1928\u1932\u1a17\u1a18\u1b34\u1b3c\u1b42\u1b80\u1b81\u1ba8\u1ba9\u1c36\u1c37\u1dfe\u1dff\u203f\u2040\u2054\u20e1\u3099\u309a\ua66f\ua67c\ua67d\ua802\ua806\ua80b\ua825\ua826\ua8c4\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\ufb1e\ufe33\ufe34\uff3f]/,
ranges: /[\x30-\x39\u0300-\u036f\u0483-\u0487\u0591-\u05bd\u0610-\u061a\u064b-\u065e\u0660-\u0669\u06d6-\u06dc\u06df-\u06e4\u06ea-\u06ed\u06f0-\u06f9\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u0941-\u0948\u0951-\u0954\u0966-\u096f\u09c1-\u09c4\u09e6-\u09ef\u0a4b-\u0a4d\u0a66-\u0a71\u0ac1-\u0ac5\u0ae6-\u0aef\u0b41-\u0b44\u0b66-\u0b6f\u0be6-\u0bef\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c66-\u0c6f\u0ce6-\u0cef\u0d41-\u0d44\u0d66-\u0d6f\u0dd2-\u0dd4\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb4-\u0eb9\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f20-\u0f29\u0f71-\u0f7e\u0f80-\u0f84\u0f90-\u0f97\u0f99-\u0fbc\u102d-\u1030\u1032-\u1037\u1040-\u1049\u105e-\u1060\u1071-\u1074\u1090-\u1099\u1712-\u1714\u1732-\u1734\u17b7-\u17bd\u17c9-\u17d3\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u1920-\u1922\u1939-\u193b\u1946-\u194f\u19d0-\u19d9\u1b00-\u1b03\u1b36-\u1b3a\u1b50-\u1b59\u1b6b-\u1b73\u1ba2-\u1ba5\u1bb0-\u1bb9\u1c2c-\u1c33\u1c40-\u1c49\u1c50-\u1c59\u1dc0-\u1de6\u20d0-\u20dc\u20e5-\u20f0\u2de0-\u2dff\u302a-\u302f\ua620-\ua629\ua8d0-\ua8d9\ua900-\ua909\ua926-\ua92d\ua947-\ua951\uaa29-\uaa2e\uaa50-\uaa59\ufe00-\ufe0f\ufe20-\ufe26\ufe4d-\ufe4f\uff10-\uff19]/,
}
};
var isInCategory = function(c, category) {
return category.ranges.test(c) || category.singles.test(c);
};
var isLetter = function(c) {
return isInCategory(c, unicode.letters);
};
var isOther = function(c) {
return isInCategory(c, unicode.others);
};
var isIdentifierStart = function(c) {
return c === "$" || c === '_' || isLetter(c);
};
var isIdentifierChar = function(c) {
return isIdentifierStart(c) || isOther(c);
};
var isIdentifier = function(s) {
if(!s.length)
return false;
if(!isIdentifierStart(s[0]))
return false;
for(var i = 1; i < s.length; i++)
if(!isIdentifierChar(s[i]))
return false;
return true;
};
module.exports = isIdentifier;
var unicode = {
letters: {
singles: '\xaa\xb5\xba\u02ec\u02ee\u0376\u0377\u0386\u038c\u0559\u066e\u066f\u06d5\u06e5\u06e6\u06ee\u06ef\u06ff\u0710\u07b1\u07f4\u07f5\u07fa\u093d\u0950\u0971\u0972\u098f\u0990\u09b2\u09bd\u09ce\u09dc\u09dd\u09f0\u09f1\u0a0f\u0a10\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a5e\u0ab2\u0ab3\u0abd\u0ad0\u0ae0\u0ae1\u0b0f\u0b10\u0b32\u0b33\u0b3d\u0b5c\u0b5d\u0b71\u0b83\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0bd0\u0c3d\u0c58\u0c59\u0c60\u0c61\u0cbd\u0cde\u0ce0\u0ce1\u0d3d\u0d60\u0d61\u0dbd\u0e32\u0e33\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0ea5\u0ea7\u0eaa\u0eab\u0eb2\u0eb3\u0ebd\u0ec6\u0edc\u0edd\u0f00\u103f\u1061\u1065\u1066\u108e\u10fc\u1258\u12c0\u17d7\u17dc\u18aa\u1bae\u1baf\u1f59\u1f5b\u1f5d\u1fbe\u2071\u207f\u2102\u2107\u2115\u2124\u2126\u2128\u214e\u2d6f\u2e2f\u3400\u4db5\u4e00\u9fc3\ua60c\ua78b\ua78c\uff70\uff9e\uff9f',
ranges: '\x41\x5a\x61\x7a\xc0\xd6\xd8\xf6\xf8\u02c1\u02c6\u02d1\u02e0\u02e4\u0370\u0374\u037a\u037d\u0388\u038a\u038e\u03a1\u03a3\u03f5\u03f7\u0481\u048a\u0523\u0531\u0556\u0561\u0587\u05d0\u05ea\u05f0\u05f2\u0621\u064a\u0671\u06d3\u06fa\u06fc\u0712\u072f\u074d\u07a5\u07ca\u07ea\u0904\u0939\u0958\u0961\u097b\u097f\u0985\u098c\u0993\u09a8\u09aa\u09b0\u09b6\u09b9\u09df\u09e1\u0a05\u0a0a\u0a13\u0a28\u0a2a\u0a30\u0a59\u0a5c\u0a72\u0a74\u0a85\u0a8d\u0a8f\u0a91\u0a93\u0aa8\u0aaa\u0ab0\u0ab5\u0ab9\u0b05\u0b0c\u0b13\u0b28\u0b2a\u0b30\u0b35\u0b39\u0b5f\u0b61\u0b85\u0b8a\u0b8e\u0b90\u0b92\u0b95\u0ba8\u0baa\u0bae\u0bb9\u0c05\u0c0c\u0c0e\u0c10\u0c12\u0c28\u0c2a\u0c33\u0c35\u0c39\u0c85\u0c8c\u0c8e\u0c90\u0c92\u0ca8\u0caa\u0cb3\u0cb5\u0cb9\u0d05\u0d0c\u0d0e\u0d10\u0d12\u0d28\u0d2a\u0d39\u0d7a\u0d7f\u0d85\u0d96\u0d9a\u0db1\u0db3\u0dbb\u0dc0\u0dc6\u0e01\u0e30\u0e40\u0e46\u0e94\u0e97\u0e99\u0e9f\u0ea1\u0ea3\u0ead\u0eb0\u0ec0\u0ec4\u0f40\u0f47\u0f49\u0f6c\u0f88\u0f8b\u1000\u102a\u1050\u1055\u105a\u105d\u106e\u1070\u1075\u1081\u10a0\u10c5\u10d0\u10fa\u1100\u1159\u115f\u11a2\u11a8\u11f9\u1200\u1248\u124a\u124d\u1250\u1256\u125a\u125d\u1260\u1288\u128a\u128d\u1290\u12b0\u12b2\u12b5\u12b8\u12be\u12c2\u12c5\u12c8\u12d6\u12d8\u1310\u1312\u1315\u1318\u135a\u1380\u138f\u13a0\u13f4\u1401\u166c\u166f\u1676\u1681\u169a\u16a0\u16ea\u16ee\u16f0\u1700\u170c\u170e\u1711\u1720\u1731\u1740\u1751\u1760\u176c\u176e\u1770\u1780\u17b3\u1820\u1877\u1880\u18a8\u1900\u191c\u1950\u196d\u1970\u1974\u1980\u19a9\u19c1\u19c7\u1a00\u1a16\u1b05\u1b33\u1b45\u1b4b\u1b83\u1ba0\u1c00\u1c23\u1c4d\u1c4f\u1c5a\u1c7d\u1d00\u1dbf\u1e00\u1f15\u1f18\u1f1d\u1f20\u1f45\u1f48\u1f4d\u1f50\u1f57\u1f5f\u1f7d\u1f80\u1fb4\u1fb6\u1fbc\u1fc2\u1fc4\u1fc6\u1fcc\u1fd0\u1fd3\u1fd6\u1fdb\u1fe0\u1fec\u1ff2\u1ff4\u1ff6\u1ffb\u2090\u2094\u210a\u2113\u2119\u211d\u212a\u212d\u212f\u2139\u213c\u213f\u2145\u2149\u2160\u2188\u2c00\u2c2e\u2c30\u2c5e\u2c60\u2c6f\u2c71\u2c7d\u2c80\u2ce4\u2d00\u2d25\u2d30\u2d65\u2d80\u2d96\u2da0\u2da6\u2da8\u2dae\u2db0\u2db6\u2db8\u2dbe\u2dc0\u2dc6\u2dc8\u2dce\u2dd0\u2dd6\u2dd8\u2dde\u3005\u3007\u3021\u3029\u3031\u3035\u3038\u303c\u3041\u3096\u309d\u309f\u30a1\u30fa\u30fc\u30ff\u3105\u312d\u3131\u318e\u31a0\u31b7\u31f0\u31ff\ua000\ua1af\ua640\ua65f\ua662\ua66d\ua67f\ua697\ua717\ua71f\ua722\ua788\ufb00\ufb06\ufb13\ufb17\uff21\uff3a\uff41\uff5a',
},
others: {
singles: '\x5f\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0670\u06e7\u06e8\u0711\u0901\u0902\u093c\u094d\u0962\u0963\u0981\u09bc\u09cd\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a51\u0a75\u0a81\u0a82\u0abc\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3f\u0b4d\u0b56\u0b62\u0b63\u0b82\u0bc0\u0bcd\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc6\u0ccc\u0ccd\u0ce2\u0ce3\u0d4d\u0d62\u0d63\u0dca\u0dd6\u0e31\u0eb1\u0ebb\u0ebc\u0f18\u0f19\u0f35\u0f37\u0f39\u0f86\u0f87\u0fc6\u1039\u103a\u103d\u103e\u1058\u1059\u1082\u1085\u1086\u108d\u135f\u1752\u1753\u1772\u1773\u17c6\u17dd\u18a9\u1927\u1928\u1932\u1a17\u1a18\u1b34\u1b3c\u1b42\u1b80\u1b81\u1ba8\u1ba9\u1c36\u1c37\u1dfe\u1dff\u203f\u2040\u2054\u20e1\u3099\u309a\ua66f\ua67c\ua67d\ua802\ua806\ua80b\ua825\ua826\ua8c4\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\ufb1e\ufe33\ufe34\uff3f',
ranges: '\x30\x39\u0300\u036f\u0483\u0487\u0591\u05bd\u0610\u061a\u064b\u065e\u0660\u0669\u06d6\u06dc\u06df\u06e4\u06ea\u06ed\u06f0\u06f9\u0730\u074a\u07a6\u07b0\u07c0\u07c9\u07eb\u07f3\u0941\u0948\u0951\u0954\u0966\u096f\u09c1\u09c4\u09e6\u09ef\u0a4b\u0a4d\u0a66\u0a71\u0ac1\u0ac5\u0ae6\u0aef\u0b41\u0b44\u0b66\u0b6f\u0be6\u0bef\u0c3e\u0c40\u0c46\u0c48\u0c4a\u0c4d\u0c66\u0c6f\u0ce6\u0cef\u0d41\u0d44\u0d66\u0d6f\u0dd2\u0dd4\u0e34\u0e3a\u0e47\u0e4e\u0e50\u0e59\u0eb4\u0eb9\u0ec8\u0ecd\u0ed0\u0ed9\u0f20\u0f29\u0f71\u0f7e\u0f80\u0f84\u0f90\u0f97\u0f99\u0fbc\u102d\u1030\u1032\u1037\u1040\u1049\u105e\u1060\u1071\u1074\u1090\u1099\u1712\u1714\u1732\u1734\u17b7\u17bd\u17c9\u17d3\u17e0\u17e9\u180b\u180d\u1810\u1819\u1920\u1922\u1939\u193b\u1946\u194f\u19d0\u19d9\u1b00\u1b03\u1b36\u1b3a\u1b50\u1b59\u1b6b\u1b73\u1ba2\u1ba5\u1bb0\u1bb9\u1c2c\u1c33\u1c40\u1c49\u1c50\u1c59\u1dc0\u1de6\u20d0\u20dc\u20e5\u20f0\u2de0\u2dff\u302a\u302f\ua620\ua629\ua8d0\ua8d9\ua900\ua909\ua926\ua92d\ua947\ua951\uaa29\uaa2e\uaa50\uaa59\ufe00\ufe0f\ufe20\ufe26\ufe4d\ufe4f\uff10\uff19'
}
};
var isInCategory = function(c, category) {
var r = category.ranges;
for(var i = 0; i < r.length - 1; i += 2)
if(c >= r[i] && c <= r[i + 1])
return true;
if(category.singles.indexOf(c) >= 0)
return true;
return false;
};
var isLetter = function(c) {
return isInCategory(c, unicode.letters);
};
var isOther = function(c) {
return isInCategory(c, unicode.others);
};
var isIdentifierStart = function(c) {
return c === "$" || c === '_' || isLetter(c);
};
var isIdentifierChar = function(c) {
return isIdentifierStart(c) || isOther(c);
};
var isIdentifier = function(s) {
if(!s.length)
return false;
if(!isIdentifierStart(s[0]))
return false;
for(var i = 1; i < s.length; i++)
if(!isIdentifierChar(s[i]))
return false;
return true;
};
module.exports = isIdentifier;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment