2010-11-26 2 views
0

Я хочу сделать проверку формы на стороне пользователя с помощью JavaScript (jQuery также используется). Цель состоит в том, чтобы удалить вложенную BBcode [quote] теги глубже, чем уровень 2. Скажем, у нас есть этот текст:JavaScript: Найти вложенные [цитата]

[quote=SoundMAX][quote=Laplundik][quote=SoundMAX] 
blahblahblah[/quote] 
blahblah 
[/quote] 
blah[/quote] 

И получите это:

[quote=SoundMAX][quote=Laplundik] 
blahblah 
[/quote] 
blah[/quote] 

Моя единственная идея состоит в том, чтобы .Привернуть [quote] с <div>, затем создайте объект DOM и удалите что-нибудь глубже, чем 2 с помощью jQuery, и проанализируйте все обратное на bbCode. Но это решение кажется слишком сложным, есть ли более элегантный?

EDIT:

Спасибо за хорошие решения. Основываясь на ответе дариоо, я сделал это:

var text=$('#edit-privatemsgbody').val(); 
var tmp=[]; 
var level=0; 

for (var i=0,l=text.length;i<l;i++){ 
if(text[i]=='['&&text[i+1]=='q') level++; 
if(text[i-6]=='q'&&text[i-7]=='/'&&text[i-8]=='[') level--; 
if(level<3) tmp.push(text[i]); 
} 
alert(tmp.join('')); 

Что работает просто отлично.

Но решение idealmachine было похоже на вспышку. Я не знал о параметрах функции обратного вызова раньше, теперь это удобно! Я соглашусь с этим.

+0

* Не * с регулярным выражением: http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454 – PleaseStand 2010-11-26 08:21:21

ответ

2

На самом деле вы можете использовать регулярное выражение, если вы посмотрите на него как на ограниченный инструмент, который не может справиться с самой вложенностью. Метод .replace строки может вызвать функцию, чтобы найти текст замены для каждого матча, что позволяет нам отслеживать, насколько глубоко мы в структуре разметки (код также размещен на http://jsfiddle.net/Zbgr3/3/):

var quoteLevel = 0; 

alert(s.replace(/\[(\/?)quote[^\]]*\]|./gi, function(tag, slash) { 
    // Opening tag? 
    if(tag.length > 1 && !slash.length) quoteLevel += 1; 
    // What to strip 
    var strip = quoteLevel > 2; 
    // Closing tag? 
    if(tag.length > 1 && slash.length) quoteLevel -= 1; 

    if(strip) return ''; 
    return tag; 
})); 

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

1

Используйте обычный массив как стек. Каждый раз, когда вы сталкиваетесь с [quote], увеличивайте свой массив на один, используя его метод push(). Когда вы сталкиваетесь с [/quote], уменьшите массив на один, используя его метод pop().

Если вы столкнулись с [quote] и длина вашего массива равна 2, удалите его [quote] и удалите следующий объект [/quote], с которым вы сталкиваетесь.

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

Смежные вопросы