2010-11-26 25 views
0

Je souhaite effectuer la validation de formulaire côté utilisateur avec JavaScript (jQuery est également utilisé). L'objectif est de supprimer bbCode imbriqués [quote] balises plus profondes que le niveau 2. Dites, nous avons ce texte:JavaScript: Rechercher imbriqué [citation]

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

Et obtenez ceci:

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

Ma seule idée est de .replace [quote] avec <div>, puis créez l'objet DOM et supprimez tout ce qui est plus profond que 2 avec jQuery, et analysez tout en arrière sur bbCode. Mais cette solution semble trop compliquée, y en a-t-il de plus élégant?

EDIT:

Merci pour les solutions agréables. Basé sur la réponse de Darioo, j'ai fait ceci:

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('')); 

Qui fonctionne très bien.

Mais la solution d'IdealMachine était comme un flash. Je ne savais pas à propos de remplacer les paramètres de fonction de rappel avant, maintenant c'est pratique! Je vais régler avec ça.

+0

* Non * avec regex: http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454 – PleaseStand

+0

@idealmachine: C'est la raison pour laquelle ont demandé une autre solution. –

Répondre

2

En fait, vous pouvez utiliser regex si vous le voyez comme un outil limité qui ne peut pas gérer l'imbrication elle-même. La méthode de chaîne .replace peut appeler une fonction pour trouver le texte de remplacement pour chaque match, ce qui nous permet de suivre la profondeur que nous sommes dans la structure de balisage (code également affiché à 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; 
})); 

Si vous voulez une certaine tolérance En cas d'erreur dans le balisage, vous pouvez ajouter du code supplémentaire qui, par exemple, empêche la chute de quoteLevel en dessous de zéro.

1

Utilise une matrice régulière en tant que pile. Chaque fois que vous rencontrez [quote], augmentez votre tableau de un en utilisant sa méthode push(). Lorsque vous rencontrez [/quote], réduisez votre tableau par un en utilisant sa méthode pop().

Si vous rencontrez [quote] et que la longueur de votre tableau est 2, supprimez ce [quote] et supprimez le [/quote] suivant.

Si vous n'avez pas le même nombre de guillemets ouverts et fermés, vous devrez gérer cela d'une manière que vous jugerez appropriée.