skip to Main Content

I have an array of names, which I use this regex /^[.*?[ЁёА-я].*?]/g filter to get those that only have Cyrillic letters in square brackets that occur at the start of the name (ex. reg1…test1 below) which works fine, I then save this regex to a database (sqlite3) as text. Now when I get it back from the table it is a string, which I need to replace with \ for the regex to work again.

I tried

  • .replace(/\/g, '\\');
  • .replace(/(?<!\)\(?!\)/g, '\\');
  • .replaceAll("\", "\\");

but as can be seen in this jsfiddle these don’t work as intended.

let arr = [
    '[Лорем ипсум долор] - Lorem ipsum dolor sit amet',
    '[Уллум велит ностер еи] sed do eiusmod tempor incididunt ut labore et dolore magna aliqua (X22)',    
    '[Пауло темпор те меа] Duis aute irure dolor (20X)',
    'Duis aute irure dolor (20X) [Пауло темпор те меа]',
    '[Lorem ipsum] sunt in culpa qui officia [Test]'
];

// Ok - this is before saving into the DB
let reg1 = /^[.*?[ЁёА-я].*?]/g;
let test1 = arr.filter(x => x.match(reg1));

// Ok - but I'd prefer not to save the regex in this form 
let reg2 = "^\[.*?[ЁёА-я].*?\]";
reg2 = new RegExp(reg2,'g');
let test2 = arr.filter(x => x.match(reg2));

// Ok - but no idea how to insert the regex part after the String.raw as 
// String.raw`${reg3}` doesn't work and String.raw(`${reg3}`) gives an error
let reg3 = String.raw`^[.*?[ЁёА-я].*?]`;
reg3 = new RegExp(reg3,'g');
let test3 = arr.filter(x => x.match(reg3));

// These don't work.
let reg4 = '^[.*?[ЁёА-я].*?]';
reg4 = reg4.replace(/\/g, '\\');
//reg4 = reg4.replace(/(?<!\)\(?!\)/g, '\\');
//reg4 = reg4.replaceAll("\", "\\");
reg4 = new RegExp(reg4,'g');
let test4 = arr.filter(x => x.match(reg4));

console.log({
    test1 : test1,
    test2 : test2,
    test3 : test3,
    test4 : test4
});

The correct result is the first three elements of the array like in the test1, test2, test3 results.

Any ideas on how to get a regex saved as a string : reg4 to work to get the correct output?

2

Answers


  1. To save regex as a string use its source:

    const r = /^[.*?[ЁёА-я].*?]/g
    console.log('the regex source is %s, but as a string in JS code it has to be escaped as %o', o.source, o.source)
    // the regex source is ^[.*?[ЁёА-я].*?], but as a string in JS code it has to be escaped as '^\[.*?[ЁёА-я].*?\]'
    
    let source = r.source
    let copy = new RegExp(source, 'g')
    console.log(r.toString() === copy.toString()) // true
    
    function copyAnyRegex(regex) {
      let source /* : string */ = regex.source
      let flags /* : string */ = regex.flags 
      return new RegExp(source, flags)
    }
    

    The regex escape slashes in string look like /w/ => "\w" (w string JSON) as they have to be escaped.
    If you want to write those strings in JS code without escaping, write regexes directly and get their source: /w/.source

    Login or Signup to reply.
  2. Since you’re already using a database, why not just change all the values :

    UPDATE yourTable SET regexColumn = REPLACE (regexColumn, '', '\');
    

    then you can use the reg2 in your example.

    or

    you could match the first [ and the last ] and add an extra backslash to those which would make your reg4 example work.

    let reg4 = '^[.*?[ЁёА-я].*?]';
    reg4 = reg4.replace(/[[]]/, '\$&');
    
    reg4 = new RegExp(reg4, 'g');
    let test4 = arr.filter(x => x.match(reg4));
    console.log(test4);
    

    jsfiddle

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search