Regex заменить, но игнорировать последний символ - PullRequest
3 голосов
/ 02 ноября 2019

Я пытаюсь заменить

/ok/how/are

на

$ok, $how, $are

, используя регулярное выражение

str.replace(/\/([0-9a-zA-Z]+)/g, '\$$1,')

, и результат равен

$ok, $how, $are, 

Я не могу использовать другое утверждение для удаления последнего ведущего ,, как я могу получить желаемый результат без последнего ,

Ответы [ 4 ]

3 голосов
/ 02 ноября 2019

Вы можете использовать две захваченные группы, одна с привязкой конца строки, другая без привязки и соответственно заменить значение

let str = `/ok/how/are`
 
let final = str.replace(/\/([a-zA-Z\d]+)$|\/([a-zA-Z\d]+)/g, (_, g1, g2) => g1 ? `$${g1}` : `$${g2}, `)
   
console.log(final)
2 голосов
/ 02 ноября 2019

Если единственная функция, которую вы можете использовать в , заменить , вы можете использовать свой шаблон и заменить запятую с пустым пробелом.

const regex = /\/([a-z0-9]+)/g;
let str = `/ok/how/are`;
str = str
  .replace(regex, "$$$1, ")
  .replace(/, $/, '');
console.log(str);

Другим вариантом без регулярного выражения может быть использование комбинации split на косой черте, map для добавления знака доллараи соедините запятой и пробелом.

Чтобы удалить пустую запись после разделения, вы можете использовать, например, .filter(Boolean)

let str = "/ok/how/are";

str = str.split("/")
  .filter(Boolean)
  .map(x => "$" + x)
  .join(", ");

console.log(str)
1 голос
/ 02 ноября 2019

Вот еще один вариант подхода, основанного на лямбда / анонимных функциях, в .replace. Это регулярное выражение использует группу перехвата внутри предвидения, которая утверждает, что у нас впереди / или конец строки.

let str = '/ok/how/are';

var repl = str.replace(/\/([a-z\d]+)(?=(\/|$))/ig, 
           ($0, $1, $2) =>  '$' + $1 + ($2 ? ", " : ""));

console.log(repl);

//=> "$ok, $how, $are"

Подробности:

  • \/([a-z\d]+): совпадение /, за которым следует 1+ буква (игнорировать регистр) илицифра
  • (?=(\/|$)): прогноз, который подтверждает наличие / или конца строки и фиксирует его во 2-й группе захвата

  • ($0, $1, $2): здесь$0 будет строкой с полным соответствием, а $1, $2 - первая и вторая группа захвата

  • '$' + $1: объединение $ и 1-я группа захвата
  • ($2 ? ", " : ""): использованиетроичный оператор принимает решение, является ли группа захвата № 2 или $2 пустой или нет. Если он не пустой, он добавляет ", " в окончательный вывод, в противном случае добавляется пустая строка.
1 голос
/ 02 ноября 2019

Возможны несколько решений: если речь идет о замене / на $ и разделении результирующих терминов запятой, это может быть жизнеспособным.

Второе решение использует именованные группы захвата ( см. Здесь и фрагмент) в вашем регулярном выражении

console.log( `$${"/ok/how/are"
  .split("\/")
  .filter(v => /^[0-9a-zA-Z]+$/g.test(v))
  .join(", $")}` );

// use es2018 named capture groups in regex
// -----------------------------------------
console.log( "/ok/how/are".replace(/\/((?<end>\w+$)|(?<within>\w+))/g,
    (...args) => {
      const { within, end } = args[args.length-1];
      return within ? `$${within}, ` :  `$${end}`;
    })
);
...