Найти подстроку, содержащую экранированную форму разделителя (Regexp) - PullRequest
0 голосов
/ 02 января 2019

Привет всем!

Я играю с уценкой, имею дело со встроенными маркерами и экранированными символами.

Проблема:

Я хочу преобразовать это: some text *some number \* other number* more text

В это: some text <strong>some number * other number</strong> more text

Моя текущая модель: /((?!\\)\*)(.*?)((?!\\)\*)/g

Но группа (.*?), похоже, захватывает символ \, поэтому третья группа находит второй символ * и прекращает поиск третьего, который должен быть его целью.

Возможное решение:

Я могу решить эту проблему, используя отрицательный взгляд: /((?<!\\)\*)(.*?)((?<!\\)\*)/g, но я бы хотел избежать этого, если это возможно.

Можно ли изменить другой шаблон, чтобы он работал?

Ответы [ 3 ]

0 голосов
/ 02 января 2019

Вы можете использовать

var str = "some text *some number \\* other number* more text";
console.log(
 str.replace(/((?:^|[^\\])(?:\\{2})*)\*([^\\*]*(?:\\[\s\S][^*\\]*)*)\*/g, 
   function($0, $1, $2) { return $1 + '<strong>' + $2.replace(/\\([\s\S])/g, '$1') + '</strong>'; }
 )
)

Первое /((?:^|[^\\])(?:\\{2})*)\*([^\\*]*(?:\\[\s\S][^*\\]*)*)\*/g регулярное выражение соответствует всем строкам в неэкранированном *:

  • ((?:^|[^\\])(?:\\{2})*) - Группа 1:
    • (?:^|[^\\]) - начало строки или без обратной косой черты
    • (?:\\{2})* - любые 0+ случаев двойного обратного слэша (это позволяет избежать совпадения *)
  • \* - * char
  • ([^\\*]*(?:\\[\s\S][^*\\]*)*) - Группа 2:
    • [^\\*]* - 0+ символов кроме \ и *
    • (?:\\[\s\S][^*\\]*)* - 0+ последовательностей
      • \\[\s\S] - \ и любой символ
      • [^*\\]* - 0+ символов, кроме \ и *
  • \* - * char.

Совпадение передается анонимному методу в качестве второго аргумента метода replace, а содержимое группы 2 обрабатывается для «отмены» любой escape-последовательности с .replace(/\\([\s\S])/g, '$1'): \\ соответствует обратной косой черте, а ([\s\S]) сопоставляет и фиксирует любой символ в Группе 1, и это то, что остается после замены заполнителем группы $1.

0 голосов
/ 02 января 2019

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

\\.|\*((\\.|[^*])+)\*

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

Код JS:

var str = `some text *some number \\* other number* more text`

console.log(str.replace(/\\.|\*((\\.|[^*])+)\*/g, function(match, $1) {
	return $1 ? '<strong>' + $1 + '</strong>' : match;
}));

Разбивка:

  • \\. Соответствует экранированному символу
  • | Или
  • \* Соответствует литералу *
  • ( Начало первой группы захвата
    • ( Начало второй группы захвата
      • \\. Соответствие экранированному символу
      • | или
      • [^*]+ Совпадение с чем угодно, кроме *
    • )+ Конец второй группы захвата, повторите один или несколько раз
    • ) Конец первой группы захвата
  • \* Соответствует литералу *
0 голосов
/ 02 января 2019

Вы можете использовать это

\*(.*)\*

Использует приведенное выше регулярное выражение для поиска * до последнего *. И затем с помощью \\(.) я нахожу сбежавшего персонажа и заменяю его захваченной группой.

const regex = /\*(.*)\*/gm;
const str = `some text *some number \\* other number* more text`;
const subst = `<strong>$1</strong>`;

// The substituted value will be contained in the result variable
const result = str.replace(regex, subst);
const finalResult = result.replace(/\\(.)/,'$1')   //replacing escaped character here

console.log(finalResult);

ОБНОВЛЕНИЕ: для сопоставления более чем одной подстроки

const regex = /\*(.*?[^\\])\*/gm;
const str = `some text *some number \\* other number* blah blah *some number \\* other number* more text`;
const subst = `<strong>$1</strong>`;

// The substituted value will be contained in the result variable
const result = str.replace(regex, subst);
const finalResult = result.replace(/\\(.)/g,'$1')   //replacing escaped character here

console.log(finalResult);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...