Я снова борюсь с регулярными выражениями. Я пытался добавить использование escape-символа для экранирования пользовательского тега, такого как <1>
до <57>
и </1>
до </57>
. С помощью Georg, здесь , следующее выражение дает желаемый результат перед попыткой метода escape.
('This is a <21>test</21> again.').split(/(<\/?(?:[1-9]|[1-4][0-9]|5[0-7])>)/);
генерирует 'This is a ', '<21>', 'test', '</21>', ' again.'
В этом вопросе есть одно предположение об использовании негативного взгляда вперед и ИЛИ для аппроксимации неподдерживаемого негативного взгляда позади. Я изменил этот пример для того, что я считал своей более простой проблемой; однако я снова в тупике.
('This is a <21>test</21> again.').split(/(?:(?!\\).|^)(<\/?(?:[1-9]|[1-4][0-9]|5[0-7])>)/) );
создает 'This is a', '<21>', 'tes', '</21>', ' again.'
Таким образом, он не включает в себя символ, предшествующий <21>
или </21>
, если не \
. И я понимаю, почему с тех пор ?:
использовал для не захвата.
Однако, если он удален, то:
('This is a <21>test</21> again.').split(/((?!\\).|^)(<\/?(?:[1-9]|[1-4][0-9]|5[0-7])>)/) );
генерирует 'This is a', ' ', '<21>', 'tes', 't', '</21>', ' again.'
А предыдущий символ генерирует отдельный сплит.
Помимо этой проблемы, экранирование работает так, что когда предыдущий символ является \
, тег не генерирует разбиение строки.
Не могли бы вы дать мне знать, если есть способ перехватить предыдущий символ, но включить его в текст предыдущей строки, а не в его собственный разделитель? И возможно исключить это только тогда, когда \
?
Когда строка 'This is a <21>test</21> again.'
, желаемый результат
'This is a ', '<21>', 'test', '</21>', ' again.'
И когда это 'This is a \<21>test</21> again.'
, желаемый результат
'This is a <21>', 'test', '</21>', ' again.'
Спасибо.
Добавление
После недавнего изучения использования встроенной функции в качестве параметра в операции replace
с использованием регулярного выражения в этом документе MDN я начал задумываться о том, можно ли сделать что-то подобное здесь. Я ничего не знаю об измерении производительности, но сложность регулярного выражения, представленного Рево ниже, и его ответ на мой комментарий об эффективности, утверждающий, что отрицательный взгляд на будущее будет значительным улучшением эффективности и меньшим объемом работы для движка RegExp, и Кроме того, что RegExp является для меня чем-то вроде тайного черного ящика, побудившего меня экспериментировать с другим подходом. Это еще пара строк кода, но он дает тот же результат и использует гораздо более короткое регулярное выражение. Все, что он на самом деле делает, - сопоставляет теги как с экранирующим символом, так и без него, вместо того, чтобы пытаться исключить экранированные с помощью \
, а затем игнорирует теги с экранирующим символом при построении массива. Фрагмент ниже.
Я не знаю, указывают ли времена, указанные в журнале консоли, на производительность, но, если это так, в примерах, которые я запускал, оказалось, что разница во времени между журналированием start
и a.split
значительно в процентах больше, чем в промежутке между a.split
и окончательной регистрацией массива a
при подходе exec
.
Кроме того, самый внутренний блок if
в операторе while
предназначен для предотвращения сохранения ""
в массиве, когда тег находится в начале или конце строки, или когда нет пробела. между двумя тегами.
Буду признателен за любую информацию, которую вы можете предоставить относительно того, почему или почему не следует использовать один подход над другим, или за представление лучшего метода в случае отсутствия доступа к истинно негативному взгляду. Спасибо.
let a, i = 0, l, p, r,
x = /\\?<\/?(?:[1-9]|[1-4]\d|5[0-7])>/g,
T = '<1>This is a <21>test<21> of \\<22>escaped and \\> </ unescaped tags.<5>';
console.log('start');
a = T.split(/((?:[^<\\]+|\\+.?|<(?!\/?(?:[1-9]|[1-4]\d|5[0-7])>))+|<\/?(?:[1-9]|[1-4]\d|5[0-7])>)/).filter(Boolean);
console.log(a);
a=[];
while ( ( r = x.exec( T ) ) !== null) {
if ( r[0].charAt(0) !== '\\' )
{
if ( r.index === 0 || r.index === p )
{
a[ i ] = r[0];
i = i + 1;
}
else
{
a[ i ] = T.substring( p, r.index );
a[ i + 1 ] = r[0];
i = i + 2;
}; // end if
p = x.lastIndex;
}; // end if
}; // next while
if ( p !== T.length ) a[i] = T.substring( p );
console.log(a)