diff --git a/index.js b/index.js index 9795fdc..ddfdba3 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,8 @@ export default function ansiRegex({onlyFirst = false} = {}) { + // Valid string terminator sequences are BEL, ESC\, and 0x9c + const ST = '(?:\\u0007|\\u001B\\u005C|\\u009C)'; const pattern = [ - '[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)', + `[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?${ST})`, '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))', ].join('|'); diff --git a/test.js b/test.js index 7c19d21..4d092d0 100644 --- a/test.js +++ b/test.js @@ -43,16 +43,18 @@ test('match only first', t => { }); test('match terminal link', t => { - t.regex('\u001B]8;k=v;https://example-a.com/?a_b=1&c=2#tit%20le\u0007click\u001B]8;;\u0007', ansiRegex()); - t.regex('\u001B]8;;mailto:no-replay@mail.com\u0007mail\u001B]8;;\u0007', ansiRegex()); - t.deepEqual('\u001B]8;k=v;https://example-a.com/?a_b=1&c=2#tit%20le\u0007click\u001B]8;;\u0007'.match(ansiRegex()), [ - '\u001B]8;k=v;https://example-a.com/?a_b=1&c=2#tit%20le\u0007', - '\u001B]8;;\u0007', - ]); - t.deepEqual('\u001B]8;;mailto:no-reply@mail.com\u0007mail-me\u001B]8;;\u0007'.match(ansiRegex()), [ - '\u001B]8;;mailto:no-reply@mail.com\u0007', - '\u001B]8;;\u0007', - ]); + for (const ST of ['\u0007', '\u001B\u005C', '\u009C']) { + t.regex(`\u000B]8;k=v;https://example-a.com/?a_b=1&c=2#tit%20le${ST}click\u001B]8;;${ST}`, ansiRegex()); + t.regex(`\u001B]8;;mailto:no-replay@mail.com${ST}mail\u001B]8;;${ST}`, ansiRegex()); + t.deepEqual(`\u001B]8;k=v;https://example-a.com/?a_b=1&c=2#tit%20le${ST}click\u001B]8;;${ST}`.match(ansiRegex()), [ + `\u001B]8;k=v;https://example-a.com/?a_b=1&c=2#tit%20le${ST}`, + `\u001B]8;;${ST}`, + ]); + t.deepEqual(`\u001B]8;;mailto:no-reply@mail.com${ST}mail-me\u001B]8;;${ST}`.match(ansiRegex()), [ + `\u001B]8;;mailto:no-reply@mail.com${ST}`, + `\u001B]8;;${ST}`, + ]); + } }); test('match "change icon name and window title" in string', t => {