|
const INITIAL_LAST_INDEX = 1; |
|
const FLAGS_LIST = ['', 'g', 'y', 'yg']; |
|
const DEMO_STR = '##-#'; |
|
const DEMO_REGEXP_PATTERN = '#'; |
|
function pushRow(table, rowDescription, callback) { |
|
const row1 = [btick(rowDescription)]; |
|
const row2 = ['']; |
|
for (const flags of FLAGS_LIST) { |
|
const str = DEMO_STR; |
|
const regExp = new RegExp(DEMO_REGEXP_PATTERN, flags); |
|
regExp.lastIndex = INITIAL_LAST_INDEX; |
|
try { |
|
const result = callback(regExp, str); |
|
if (resultToString(result) === undefined) { |
|
throw new Error({rowDescription, regExp, str}); |
|
} |
|
row1.push(resultToString(result)); |
|
row2.push(lastIndexToString(regExp.lastIndex)); |
|
} catch (err) { |
|
if (! (err instanceof TypeError)) { |
|
throw err; |
|
} |
|
row1.push(btick(err.constructor.name)); |
|
row2.push(''); |
|
} |
|
} |
|
table.push(row1); |
|
table.push(row2); |
|
} |
|
|
|
function lastIndexToString(lastIndex) { |
|
if (lastIndex === 0) { |
|
return '`.lI` reset'; |
|
} else if (lastIndex === INITIAL_LAST_INDEX) { |
|
return '`.lI` unch'; |
|
} else { |
|
return '`.lI` upd'; |
|
} |
|
} |
|
|
|
function isMatchObject(value) { |
|
return value && typeof value === 'object' && 'index' in value; |
|
} |
|
|
|
function toMatchObjectString(matchObject) { |
|
return '{i:'+matchObject.index+'}'; |
|
} |
|
|
|
function btick(str) { |
|
return '`' + str + '`'; |
|
} |
|
|
|
function resultToString(result) { |
|
if (isMatchObject(result)) { |
|
return btick(toMatchObjectString(result)); |
|
} else if (Array.isArray(result) && result.every(elem => isMatchObject(elem))) { |
|
return btick('[' + result.map(x => toMatchObjectString(x)).join(', ') + ']'); |
|
} else if (['number', 'boolean', 'string'].includes(typeof result) || Array.isArray(result)) { |
|
return btick(JSON.stringify(result)); |
|
} else { |
|
throw new Error(result); |
|
} |
|
} |
|
|
|
function extractColumn(table, colIndex) { |
|
return table.map(row => row[colIndex]); |
|
} |
|
function getWidthOfColumn(table, colIndex) { |
|
return Math.max(...extractColumn(table, colIndex).map( |
|
str => typeof str === 'string' ? str.length : 0)); |
|
} |
|
const DASHES = Symbol('DASHES'); |
|
function printTable(table) { |
|
const columnWidths = [...table[0].keys()].map( |
|
(colIndex) => getWidthOfColumn(table, colIndex)); |
|
for (const row of table) { |
|
let rowStr = row |
|
.map((cell, colIndex) => { |
|
if (cell === DASHES) { |
|
return '-'.repeat(columnWidths[colIndex]); |
|
} else { |
|
return cell.padEnd(columnWidths[colIndex]) |
|
} |
|
}) |
|
.join(' | '); |
|
rowStr = '| ' + rowStr + ' |'; |
|
console.log(rowStr); |
|
} |
|
} |
|
|
|
function main() { |
|
const table = []; |
|
|
|
table.push(['', ...FLAGS_LIST.map(flags => btick('/'+flags))]); |
|
table.push(new Array(table[0].length).fill(DASHES)); |
|
|
|
pushRow(table, 'r.exec(s)', (re, str) => re.exec(str)); |
|
pushRow(table, 'r.test(s)', (re, str) => re.test(str)); |
|
|
|
pushRow(table, 's.match(r)', (re, str) => str.match(re)); |
|
pushRow(table, 's.matchAll(r)', (re, str) => [...str.matchAll(re)]); |
|
|
|
pushRow(table, "s.replace(r, 'x')", (re, str) => str.replace(re, 'x')); |
|
pushRow(table, "s.replaceAll(r, 'x')", (re, str) => str.replaceAll(re, 'x')); |
|
|
|
printTable(table); |
|
|
|
console.log(); |
|
console.log('Variables:'); |
|
console.log(); |
|
console.log('```js'); |
|
console.log(`const r = ${new RegExp(DEMO_REGEXP_PATTERN, '')}; r.lastIndex = 1;`); |
|
console.log(`const s = ${JSON.stringify(DEMO_STR)};`); |
|
console.log('```'); |
|
} |
|
|
|
main(); |