Как я могу преобразовать это регулярное выражение, чтобы быть JS безопасно? - PullRequest
0 голосов
/ 10 октября 2018

В приведенном ниже коде у меня есть r = мое регулярное выражение.Который затем проверяется на соответствие заданным s-строкам для поиска совпадений, которые находят первую включенную подстроку между @ и пробелом, где @ должен либо начинать тестовую строку, либо он должен следовать за пробелом.

const test = (s) => {
  let r = /(?<=^@|\s@)[^\s]+/g;
  let a = r.exec(s);
  if (a)
    console.log(`given: ${s}, found: ${a[0]}`);
  else
    console.log(`given: ${s}, no match found.`);
}

test("@abc"); // match = 'abc'
test("abc @def"); // match = 'def'
test("abc@def"); // no match
test("@abc@def"); // match = 'abc@def'
test("abc@def @ghi"); // match = 'ghi'
test("abd def"); // no match
test("@abd @def"); // match = 'abc' (only)

Проблема заключается в том, что, хотя это работает в Chrome, оно не работает в Firefox (SyntaxError: недопустимая группа regexp), и поэтому? <= Lookbehind не является js-безопасным.Можете проверить это, открыв chrome и firefox, перейдя на codepen.io.вставка кода в область JS.И просмотрите консоль codepen в Chrome (увидите результаты), и консоль инструментов Firefox dev увидит ошибку, а в консоли codepen никаких результатов. </p>

Может кто-нибудь посоветовать, как я могу преобразовать это в js-безопасный, но все же работатьто же самое.

Примечание (?: ^ @ | \ s @) [^ \ s] + близко, но оно содержит символ @ и все начальные пробелы.(Да, можно легко заменить, но мне интересно, есть ли безопасный способ сделать это с помощью js).

1 Ответ

0 голосов
/ 10 октября 2018

Вместо просмотра назад используйте группу без захвата вместо @.Затем захватите следующие непробельные символы в группе.Если ваш объект сопоставления не равен нулю, то печать [1] st-индекса даст вам содержимое этой группы захвата.

Убедитесь, что вы не используете глобальный флаг (по крайней мере, не в этой реализации)- при /g вы получите массив всех полных совпадений , но без информации о захваченных группах.

Также обратите внимание, что [^\s] упрощается до \S (любой несимвол пробела):

const test = (str) => {
  const regex = /(?:^@|\s@)(\S+)/;
  const match = str.match(regex);
  if (match) {
    console.log(`given: ${str}, found: ${match[1]}`);
    }
  else
    console.log(`given: ${str}, no match found.`);
}

test("@abc");          // match = 'abc'
test("abc @def");      // match = 'def'
test("abc@def");       // no match
test("@abc@def");      // match = 'abc@def'
test("abc@def @ghi");  // match = 'ghi'
test("abd def");       // no match
test("@abd @def");     // match = 'abc' (only)
...