Заменить 5 replace на 1 regexp | JS

153
28 мая 2022, 19:50

Очень мозолит глаза вот такая конструкция:

let url = NameController
                        .replace(`${root_path}/${_path_url}`, "")
                        .replace('.js', "")
                        .replace('index', "")
                        .replace(/\[/g, ":")
                        .replace(/\]/g, "")

в NameController следующая строка D:/JS/vkma/api/controllers/test.js

условия такие: Нужно удалить все по слову controllers включая его... в итоге получаем /test.js

Далее если есть слово index НО оно в чистом виде... indexA удалятся не должно. Так же index заменять только в именах файлов. получается только если справа от слова есть " . "

Потом если у /test.js есть [ и ] то надо их заменить.. вот пример: /[test].js нужно получить /:test.js

Ну и последнее это удалить расширение файла .js чтоб получить /:test если были скобки... либо /test если скобок небыло.

Как реализовать подобное регулярное выражение?

Answer 1

Заменяются ведь на разные вещи (на пустую строку или двоеточие), уже не получится одной регуляркой и без дополнительных операций. Если очень хочется убрать с глаз что-то многострочное, можно завернуть его в функцию.

Можно не удалять всё ненужное, а выбрать только нужное, через match():

console.log( get_name("D:/JS/vkma/api/controllers/test.js") );
console.log( get_name("D:/JS/vkma/api/controllers/[test].js") );
console.log( get_name("D:/JS/vkma/api/controllers/testindex.js") );
console.log( get_name("D:/JS/vkma/api/controllers/indexA.js") );
console.log( get_name("D:/JS/vkma/api/controllers/[testindex].js") );
console.log( get_name("D:/JS/vkma/api/controllers/index.js") );

function get_name(nameController) {
  let match = nameController.match(/\/\[?([^./]+?)(?:index)?\.js/);
  
  return match && match[1].replace(/\]/g, ":");
}

Справки:

  • ? — совпадене 0 или 1 раз, \[? — необязательная открывающая скобка.
  • ([^./]+?) — группа захвата (match вернет массив, в котором под [1]-м индексом будет всё, что совпало в скобках). [^./] — внутри квадратных скобок перечисляются символы, один из которых должен совпасть. Если список начинается с ^ (отрицания), читается «Все что угодно, кроме . или /», и + — один или много раз подряд.
  • (?:index) скобки начинаются с ?: — «не группа захвата».
  • match && match[1] — Особенность логического "И": Если совпадения не будет и match вернет null, в логическом контексте это false. Вернется null и вторая часть выражения даже не будет вычисляться, не будет ошибки. Можно было заменить на if-else.

P.s.

Беспокоюсь о производительности этих replace один за одним

for (let i = 0; i < 10; i++) {
  setTimeout(test);
}
function test() {
  let start = performance.now();
  let x = "11111";
  for (let i = 0; i < 1000000; i++) {
    x.replace(/1/g, "2").replace(/2/g, "1");
  }
  
  console.log(performance.now() - start);
}

Справляется с миллионами, наверно можно не беспокоиться за +/-4 штуки) Длина строки тоже имеет значение, но она у вас короткая.

Answer 2

С index не вполне понятно, что именно нужно удалять.

const NameController = 'D:/JS/vkma/api/controllers/[test]index.js';
const base = require('path').basename(NameController, '.js');
// const base = NameController.split('/controllers/')[1].replace(/\.js$/, '');
let result = '/' + base
    .replace(/\[(.*)\]/, '$1:')
    .replace(/\bindex\b/g, '');
console.log(result); // /test:
READ ALSO
Как развернуть React приложение?

Как развернуть React приложение?

Как развернуть собранное React-приложение на компоненты? Приложение имеет вот такой вид в собранном состоянии у меня на локальном сервере:

129
Настройка Webpack

Настройка Webpack

У меня возникло 2 ошибки в консоли

173
Сессия в Node.js быстро сбрасывается

Сессия в Node.js быстро сбрасывается

Сессия устанавливается после авторизацииЕсли попереключаться по ссылкам внутри сайта, все работает нормально

187