Экранировать пользовательский ввод для помещения в регулярку

В C# для этого есть готовая функция Regex.Escape, а что для этих целей использовать в js?


Ответы (1 шт):

Автор решения: Qwertiy

Функция:

const escapeForRegExp = (s: string) => s.replace(/[[\]{}.()?+*^$\\|]/g, "\\$&");

Юнит-тест:

describe("escapeForRegExp", () => {
  it("should properly escape all characters", () => {
    const all = Array(129).fill("").map((x, i) => String.fromCharCode(i)).join("");
    const all2 = all + all;
    const allr = Array.from(all).reverse().join("");

    for (const ch of all) {
      const escaped = escapeForRegExp(ch);

      assert.strictEqual(all.replace(RegExp(escaped, "g"), ""), all.split(ch).join(""), `when char is ${JSON.stringify(ch)}`);
      assert.strictEqual(all2.replace(RegExp(escaped, "g"), ""), all2.split(ch).join(""), `when char is ${JSON.stringify(ch)} and string is doubled`);
      assert.strictEqual(allr.replace(RegExp(escaped, "g"), ""), allr.split(ch).join(""), `when char is ${JSON.stringify(ch)} on reversed string`);
    }

    assert.strictEqual(all.replace(RegExp(escapeForRegExp(all)), ""), "", `Should replace the whole string`);
    assert.strictEqual(all2.replace(RegExp(escapeForRegExp(all)), ""), all, `Should replace the whole string once in doubled`);
    assert.strictEqual(allr.replace(RegExp(escapeForRegExp(all)), ""), allr, `Should NOT replace anything on reversed string`);
  });
});

Обращаю внимание, что тест не полагается ни на перечень спецсимволов, ни на ожидаемый результат экранирования, а проверяет работоспособность полученной регулярки. Однако ожидается, что коды спецсимволов не превосходят 128.

→ Ссылка