Мне очень трудно работать с регулярными выражениями, и я очень ценю любую помощь или направление, которое вы можете оказать.
Следующее выражение работает (со сложной, по крайней мере для меня, передней частью в 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, вставьте теги.