Skip to content

Commit 8a39eee

Browse files
committed
Allow unicode key names
1 parent f07b289 commit 8a39eee

File tree

1 file changed

+20
-29
lines changed

1 file changed

+20
-29
lines changed

src/index.ts

Lines changed: 20 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ const DEFAULT_PREFIXES = "./";
22
const DEFAULT_DELIMITER = "/";
33
const GROUPS_RE = /\((?:\?<(.*?)>)?(?!\?)/g;
44
const NOOP_VALUE = (value: string) => value;
5+
const NAME_RE = /^[\p{L}\p{Nl}\p{Mn}\p{Mc}\p{Nd}\p{Pc}]$/u;
56

67
/**
78
* Encode a string into another string.
@@ -98,50 +99,40 @@ interface LexToken {
9899
* Tokenize input string.
99100
*/
100101
function lexer(str: string) {
102+
const chars = [...str];
101103
const tokens: LexToken[] = [];
102104
let i = 0;
103105

104-
while (i < str.length) {
105-
const char = str[i];
106+
while (i < chars.length) {
107+
const char = chars[i];
106108

107109
if (char === "*" || char === "+" || char === "?") {
108-
tokens.push({ type: "MODIFIER", index: i, value: str[i++] });
110+
tokens.push({ type: "MODIFIER", index: i, value: chars[i++] });
109111
continue;
110112
}
111113

112114
if (char === "\\") {
113-
tokens.push({ type: "ESCAPED_CHAR", index: i++, value: str[i++] });
115+
tokens.push({ type: "ESCAPED_CHAR", index: i++, value: chars[i++] });
114116
continue;
115117
}
116118

117119
if (char === "{") {
118-
tokens.push({ type: "OPEN", index: i, value: str[i++] });
120+
tokens.push({ type: "OPEN", index: i, value: chars[i++] });
119121
continue;
120122
}
121123

122124
if (char === "}") {
123-
tokens.push({ type: "CLOSE", index: i, value: str[i++] });
125+
tokens.push({ type: "CLOSE", index: i, value: chars[i++] });
124126
continue;
125127
}
126128

127129
if (char === ":") {
128130
let name = "";
129131
let j = i + 1;
130132

131-
while (j < str.length) {
132-
const code = str.charCodeAt(j);
133-
134-
if (
135-
// `0-9`
136-
(code >= 48 && code <= 57) ||
137-
// `A-Z`
138-
(code >= 65 && code <= 90) ||
139-
// `a-z`
140-
(code >= 97 && code <= 122) ||
141-
// `_`
142-
code === 95
143-
) {
144-
name += str[j++];
133+
while (j < chars.length) {
134+
if (NAME_RE.test(chars[j])) {
135+
name += chars[j++];
145136
continue;
146137
}
147138

@@ -160,30 +151,30 @@ function lexer(str: string) {
160151
let pattern = "";
161152
let j = i + 1;
162153

163-
if (str[j] === "?") {
154+
if (chars[j] === "?") {
164155
throw new TypeError(`Pattern cannot start with "?" at ${j}`);
165156
}
166157

167-
while (j < str.length) {
168-
if (str[j] === "\\") {
169-
pattern += str[j++] + str[j++];
158+
while (j < chars.length) {
159+
if (chars[j] === "\\") {
160+
pattern += chars[j++] + chars[j++];
170161
continue;
171162
}
172163

173-
if (str[j] === ")") {
164+
if (chars[j] === ")") {
174165
count--;
175166
if (count === 0) {
176167
j++;
177168
break;
178169
}
179-
} else if (str[j] === "(") {
170+
} else if (chars[j] === "(") {
180171
count++;
181-
if (str[j + 1] !== "?") {
172+
if (chars[j + 1] !== "?") {
182173
throw new TypeError(`Capturing groups are not allowed at ${j}`);
183174
}
184175
}
185176

186-
pattern += str[j++];
177+
pattern += chars[j++];
187178
}
188179

189180
if (count) throw new TypeError(`Unbalanced pattern at ${i}`);
@@ -194,7 +185,7 @@ function lexer(str: string) {
194185
continue;
195186
}
196187

197-
tokens.push({ type: "CHAR", index: i, value: str[i++] });
188+
tokens.push({ type: "CHAR", index: i, value: chars[i++] });
198189
}
199190

200191
tokens.push({ type: "END", index: i, value: "" });

0 commit comments

Comments
 (0)