Skip to content

Instantly share code, notes, and snippets.

@rauschma
Last active January 25, 2021 08:57
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rauschma/5c90e6c19923611521a61e199d8cb15b to your computer and use it in GitHub Desktop.
Save rauschma/5c90e6c19923611521a61e199d8cb15b to your computer and use it in GitHub Desktop.
Table: RegExp flags `/g` and `/y`

Table: RegExp flags /g and /y

The following table was generated by the Node.js script:

/ /g /y /yg
r.exec(s) {i:0} {i:1} {i:1} {i:1}
.lI unch .lI upd .lI upd .lI upd
r.test(s) true true true true
.lI unch .lI upd .lI upd .lI upd
s.match(r) {i:0} ["#","#","#"] {i:1} ["#","#"]
.lI unch .lI reset .lI upd .lI reset
s.matchAll(r) TypeError [{i:1}, {i:3}] TypeError [{i:1}]
.lI unch .lI unch
s.replace(r, 'x') "x#-#" "xx-x" "#x-#" "xx-#"
.lI unch .lI reset .lI upd .lI reset
s.replaceAll(r, 'x') TypeError "xx-x" TypeError "xx-#"
.lI reset .lI reset

Variables:

const r = /#/; r.lastIndex = 1;
const s = "##-#";

Abbreviations:

  • {i:2}: a match object whose property .index has the value 2.
  • .lI upd: .lastIndex is updated
  • .lI reset: .lastIndex is reset to zero
  • .lI unch: .lastIndex is unchanged
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();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment