(itemsArr)
| 215 | * @returns {string} regexp |
| 216 | */ |
| 217 | const itemsToRegexp = (itemsArr) => { |
| 218 | if (itemsArr.length === 1) { |
| 219 | return quoteMeta(itemsArr[0]); |
| 220 | } |
| 221 | /** @type {string[]} */ |
| 222 | const finishedItems = []; |
| 223 | |
| 224 | // merge single char items: (a|b|c|d|ef) => ([abcd]|ef) |
| 225 | let countOfSingleCharItems = 0; |
| 226 | for (const item of itemsArr) { |
| 227 | if (item.length === 1) { |
| 228 | countOfSingleCharItems++; |
| 229 | } |
| 230 | } |
| 231 | // special case for only single char items |
| 232 | if (countOfSingleCharItems === itemsArr.length) { |
| 233 | return `[${charsToCharClassContent(itemsArr)}]`; |
| 234 | } |
| 235 | /** @type {Set<string>} */ |
| 236 | const items = new Set(itemsArr.sort()); |
| 237 | if (countOfSingleCharItems > 2) { |
| 238 | /** @type {string[]} */ |
| 239 | const singleCharItems = []; |
| 240 | for (const item of items) { |
| 241 | if (item.length === 1) { |
| 242 | singleCharItems.push(item); |
| 243 | items.delete(item); |
| 244 | } |
| 245 | } |
| 246 | finishedItems.push(`[${charsToCharClassContent(singleCharItems)}]`); |
| 247 | } |
| 248 | |
| 249 | // special case for 2 items with common prefix/suffix |
| 250 | if (finishedItems.length === 0 && items.size === 2) { |
| 251 | const prefix = getCommonPrefix(itemsArr); |
| 252 | const suffix = getCommonSuffix( |
| 253 | itemsArr.map((item) => item.slice(prefix.length)) |
| 254 | ); |
| 255 | if (prefix.length > 0 || suffix.length > 0) { |
| 256 | return `${quoteMeta(prefix)}${itemsToRegexp( |
| 257 | itemsArr.map((i) => i.slice(prefix.length, -suffix.length || undefined)) |
| 258 | )}${quoteMeta(suffix)}`; |
| 259 | } |
| 260 | } |
| 261 | |
| 262 | // special case for 2 items with common suffix |
| 263 | if (finishedItems.length === 0 && items.size === 2) { |
| 264 | /** @type {SetIterator<string>} */ |
| 265 | const it = items[Symbol.iterator](); |
| 266 | const a = /** @type {string} */ (it.next().value); |
| 267 | const b = /** @type {string} */ (it.next().value); |
| 268 | if (a.length > 0 && b.length > 0 && a.slice(-1) === b.slice(-1)) { |
| 269 | return `${itemsToRegexp([a.slice(0, -1), b.slice(0, -1)])}${quoteMeta( |
| 270 | a.slice(-1) |
| 271 | )}`; |
| 272 | } |
| 273 | } |
| 274 |
no test coverage detected