2010-03-01 6 views
3
text = '#container a.filter(.top).filter(.bottom).filter(.middle)'; 

regex = /(.*?)\.filter\((.*?)\)/; 

matches = text.match(regex); 

log(matches); 
// matches[1] is '#container a' 
//matchss[2] is '.top' 

Je me attends à capturerexpression régulière pour analyser la chaîne comme jQuery sélecteur

matches[1] is '#container a' 
matches[2] is '.top' 
matches[3] is '.bottom' 
matches[4] is '.middle' 

Une solution serait de diviser la chaîne en #container un et de repos. Ensuite, prenez le repos et exécutez exec récursive pour obtenir l'élément à l'intérieur().

Mise à jour: Je poste une solution qui fonctionne. Cependant je cherche une meilleure solution. N'aimez pas vraiment l'idée de diviser la chaîne et ensuite le traitement Voici une solution qui fonctionne.

matches = []; 

var text = '#container a.filter(.top).filter(.bottom).filter(.middle)'; 
var regex = /(.*?)\.filter\((.*?)\)/; 
var match = regex.exec(text); 
firstPart = text.substring(match.index,match[1].length); 
rest = text.substring(matchLength, text.length); 

matches.push(firstPart); 

regex = /\.filter\((.*?)\)/g; 
while ((match = regex.exec(rest)) != null) { 
    matches.push(match[1]); 
} 
log(matches); 

Vous cherchez une meilleure solution.

Répondre

5

Cela correspondra à l'exemple simple que vous avez posté:

<html> 
    <body> 
    <script type="text/javascript"> 
     text = '#container a.filter(.top).filter(.bottom).filter(.middle)'; 
     matches = text.match(/^[^.]*|\.[^.)]*(?=\))/g); 
     document.write(matches); 
    </script> 
    </body> 
</html> 

qui produit:

#container a,.top,.bottom,.middle 

EDIT

Voici une brève explication:

^   # match the beginning of the input 
[^.]*  # match any character other than '.' and repeat it zero or more times 
      # 
|   # OR 
      # 
\.  # match the character '.' 
[^.)]* # match any character other than '.' and ')' and repeat it zero or more times 
(?=  # start positive look ahead 
    \)  # match the character ')' 
)   # end positive look ahead 

EDIT partie II

Le regex cherche deux types de séquences de caractères:

  1. un ou plusieurs caractères en partant du début de la chaîne jusqu'au premier ., l'expression rationnelle: ^[^.]*
  2. ou correspond à une séquence de caractères commençant par . suivie de zéro ou plusieurs caractères autres que . et ), \.[^.)]*, mais doit avoir un ) en avance sur celui-ci: (?=\)). Cette dernière condition provoque .filterpas pour correspondre.
+0

très bien fait. Je vais devoir lire un livre regex pour comprendre le look-ahead –

+0

Je ne reçois pas ce code. Quelqu'un peut-il expliquer? –

+0

@Raj, @dorelal, voir mon édition. Et merci Raj. –

0

Vous devez faire plusieurs matchs à plusieurs reprises, en commençant où les dernières extrémités du match (voir while exemple à https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/RegExp/exec):

Si votre expression régulière utilise le drapeau « g », vous pouvez utiliser le multiple de la méthode exec fois pour trouver des correspondances successives dans la même chaîne. Lorsque vous le faites, la recherche commence à la sous-chaîne de str spécifiée par la propriété lastIndex de l'expression régulière. Par exemple, supposons que vous avez ce script:

var myRe = /ab*/g; 
var str = "abbcdefabh"; 
var myArray; 
while ((myArray = myRe.exec(str)) != null) 
{ 
    var msg = "Found " + myArray[0] + ". "; 
    msg += "Next match starts at " + myRe.lastIndex; 
    print(msg); 
} 

Ce script affiche le texte suivant:

Found abb. Next match starts at 3 
Found ab. Next match starts at 9 

Cependant, ce cas serait mieux résolu en utilisant un analyseur intégré personnalisé. Les expressions régulières ne sont pas une solution efficace à ce problème, si vous me le demandez.

+0

J'ai posté une solution qui fonctionne. Cependant je cherche une meilleure solution. –

3

Vous devez itérer, je pense.

var head, filters = []; 
text.replace(/^([^.]*)(\..*)$/, function(_, h, rem) { 
    head = h; 
    rem.replace(/\.filter\(([^)]*)\)/g, function(_, f) { 
    filters.push(f); 
    }); 
}); 
console.log("head: " + head + " filters: " + filters); 

La possibilité d'utiliser des fonctions comme deuxième argument de chaîne.remplacer est l'une de mes choses préférées sur Javascript :-)

+0

très bien fait. Aimer. Jamais vu l'utilisation de remplacer dans le contexte regex. Je vous remercie. C'est essentiellement la même chose que moi. Cependant ce code montre qu'il s'agit du code d'un pro. –

+0

merci monsieur :-) – Pointy

0
var text = '#container a.filter(.top).filter(.bottom).filter(.middle)'; 
var result = text.split('.filter'); 

console.log(result[0]); 
console.log(result[1]); 
console.log(result[2]); 
console.log(result[3]); 
+0

au lieu de .top vous obtiendrez (.top) –

+0

'résultat [0] .replace (/ \ (| \)/g, '')' –

0

text.split() avec regex le tour est joué.

var text = '#container a.filter(.top).filter(.bottom).filter(.middle)'; 
var parts = text.split(/(\.[^.()]+)/); 
var matches = [parts[0]]; 

for (var i = 3; i < parts.length; i += 4) { 
    matches.push(parts[i]); 
} 

console.log(matches); 
Questions connexes