RegExp с переменной частью и обходной путь для негативного просмотра в Firefox - PullRequest
0 голосов
/ 17 апреля 2019

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

Следующее выражение работает (со сложной, по крайней мере для меня, передней частью в Firefox, поскольку в настоящее время нет поддержки негативного взгляда), чтобы разбить строку на значения пользовательских тегов <1> до <57> и от </1> до </57>, исключая экранированные, такие как \<22> или \</17>, где T - строка простого текста.

array = T.split(/((?:[^<\\]+|\\+.?|<(?!\/?(?:[1-9]|[1-4]\d|5[0-7])>))+|<\/?(?:[1-9]|[1-4]\d|5[0-7])>)/).filter(Boolean);

Теперь я хотел бы найти строку для определенного тега, типа открытия или закрытия. Таким образом, new RegExp требуется, поскольку сегменты [1-9]|[1-4]\d|[5][0-7] необходимо заменить переменной строкой с целым целым значением от 1 до 57.

Я безуспешно попробовал несколько str.replace() предложений из других вопросов, чтобы получить правильный шаблон регулярного выражения. Двое были:

replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');

replace(/[.*+?^${}()|[\]\\]/g, '\\$&');

К счастью, добавление \ для каждого \ привело к правильному выражению. Однако следующее всегда возвращает true.

n = '22';
t = '((?:[^<\\\\]+|\\\\+.?|<(?!\\/?(?:' + n + ')>))+|<\\/?(?:' + n + ')>)';
r = new RegExp( t , 'g' );
console.log( r.test('test\\\<21>') );

Эта строка 'test\\\<21>' должна возвращать false, даже если n было 21, потому что ей предшествует \; но он возвращает true для четного n = 22, и кажется, что все строки в test возвращают true.

Я понимаю, что это регулярное выражение - это ИЛИ двух шаблонов; правый шаблон - это допустимые теги, а левый юниверс - без допустимых тегов. Теги захватываются, а вселенная, кроме тегов, не фиксируется.

((?:[^<\\\\]+|\\\\+.?|<(?!\\/?(?:' + n + ')>))+

|

<\\/?(?:' + n + ')>)

Возможно, в этом проблема. @Revo дал мне отрицательный взгляд назад здесь и описывает, как это работает. И @Georg помог мне с положительной фигурой здесь .

Если t изменяется только на правый шаблон, он работает как положено, но не исключает теги с префиксом \.

Как можно преобразовать регулярное выражение, работающее в методе split, в работу в операциях test и replace, включая подход «отрицательный взгляд за», чтобы исключить экранированные теги? Похоже, что не зафиксированная часть все еще регистрирует совпадение; но я не уверен.

Мне нужно проверить выбранную пользователем строку на наличие '<' + n + '>' или '</' + n + '>', но не на экранированных версиях с префиксом \. Если он найден, замените его ничем ''. Если не найдено, то необходимо добавить определенные теги. Это добавление тегов у меня работает.

Спасибо, что рассмотрели мой вопрос и любое направление, которое вы можете предоставить.

Добавление Хотя я не нашел ответа на свой конкретный вопрос о том, как настроить регулярное выражение для исключения префикса \, документы Mozilla Developer показали лучший подход в целом с использованием replace с функцией в качестве параметра. Таким образом, вместо того, чтобы пытаться исключить экранированные теги из регулярного выражения, просто дайте им соответствовать и верните соответствие, если первый символ был \. Пример решения ниже.

let n = '22', 
    t = '\\\\?<\\/?(?:' + n + ')>',
    r = new RegExp( t, 'g' ),
    x, str = '<21>This is \\ > \\<21> a \\<22>test</22> of </21>';

x = str.replace( r, (match) => { return match.charAt(0) === '\\' ? match : ''; } );
console.log( 'x = ' + x );

Результат x = <21>This is \ > \<21> a \<22>test of </21>. Таким образом, сбежавший \<22> остается, а не спасенный </22> удаляется. Простой для тех, кто знает, я уверен, но новый для меня.

Это хорошо для операции замены, но не помогает в тестировании на наличие только неэкранированных тегов. Без негативного оглядки назад, я думаю, можно сначала выполнить замену строки только для экранированных тегов и удалить их, а затем проверить результат на неэкранированные теги. Если true, тогда запустите приведенный выше пример замены для исходной строки; и, если false, вставьте теги.

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