Comment transformer l'expression régulière en non gourmand?

227

J'utilise jQuery. J'ai une chaîne avec un bloc de caractères spéciaux (début et fin). Je veux récupérer le texte de ce bloc de caractères spéciaux. J'ai utilisé un objet d'expression régulière pour la recherche dans la chaîne. Mais comment puis-je dire à jQuery de trouver plusieurs résultats lorsque vous avez deux caractères spéciaux ou plus?

Mon HTML:

<div id="container">
    <div id="textcontainer">
     Cuc chiến pháp lý gia [|cơ thử|nghim|] th trường [|test2|đây là test ln 2|] chng khoán [|Mỹ|day la nuoc my|] và ngân hàng đầu tư quyn lc nht Ph Wall mi ch bt đầu.
    </div>
</div>

et mon code JavaScript:

$(document).ready(function() {
  var takedata = $("#textcontainer").text();
  var test = 'abcd adddb';
  var filterdata = takedata.match(/(\[.+\])/);

  alert(filterdata); 

  //end write js 
});

Mon résultat est: [| cơ thử | nghiệm |] thị trường [| test2 | đây là test lần 2 |] chứng khoán [| Mỹ | jour la nuoc my |] . Mais ce n'est pas le résultat que je veux :(. Comment obtenir [texte] pour les temps 1 et [démo] pour les temps 2?


Je viens de faire mon travail après avoir cherché des informations sur internet ^^. Je fais du code comme ça:

var filterdata = takedata.match(/(\[.*?\])/g);
  • mon résultat est: [| cơ thử | nghiệm |], [| test2 | đây là test lần 2 |] c'est vrai !. mais je ne comprends pas vraiment cela. Pouvez-vous me répondre pourquoi?
Rueta
la source

Réponses:

492

Les modificateurs de regex non gourmands sont comme leurs homologues gourmands mais avec un ?immédiatement après eux:

*  - zero or more
*? - zero or more (non-greedy)
+  - one or more
+? - one or more (non-greedy)
?  - zero or one
?? - zero or one (non-greedy)
Asaph
la source
29
pourrait être utile de noter que ?signifie à lui seul «un ou zéro» (mais est gourmand!). Par exemple 'bb'.replace(/b?/, 'a') //'ab'et'bb'.replace(/c?/, 'a') //'abb'
Hashbrown
1
comment c ne correspondait à rien
Muhammad Umer
1
@MuhammadUmer Je pense qu'il suggérait cela parce que le cne correspondra pas, mais vous avez le ?, ce qui est 0 or 1, alors il va correspondre 0 number of c characters, donc le remplacer. Je ne sais pas comment cela fonctionne, car cela ne se compile dans aucun moteur regex que j'ai essayé 😢
Noctis
35

Vous avez raison de dire que la cupidité est un problème:

--A--Z--A--Z--
  ^^^^^^^^^^
     A.*Z

Si vous voulez faire correspondre les deux A--Z, vous devrez utiliser A.*?Z(le ?rend le *"réticent", ou paresseux).

Il existe parfois de meilleures façons de le faire, par exemple,

A[^Z]*+Z

Cela utilise une classe de caractères nié et un quantificateur possessif, pour réduire le retour en arrière, et est probablement plus efficace.

Dans votre cas, l'expression régulière serait:

/(\[[^\]]++\])/

Malheureusement, regex Javascript ne prend pas en charge les quantificateurs possessifs, vous n'avez donc qu'à faire avec:

/(\[[^\]]+\])/

Voir également


Résumé rapide

*   Zero or more, greedy
*?  Zero or more, reluctant
*+  Zero or more, possessive

+   One or more, greedy
+?  One or more, reluctant
++  One or more, possessive

?   Zero or one, greedy
??  Zero or one, reluctant
?+  Zero or one, possessive

Notez que les quantificateurs réticents et possessifs sont également applicables aux {n,m}constructions à répétition finie .

Exemples en Java:

System.out.println("aAoZbAoZc".replaceAll("A.*Z", "!"));  // prints "a!c"
System.out.println("aAoZbAoZc".replaceAll("A.*?Z", "!")); // prints "a!b!c"

System.out.println("xxxxxx".replaceAll("x{3,5}", "Y"));  // prints "Yx"
System.out.println("xxxxxx".replaceAll("x{3,5}?", "Y")); // prints "YY"
polygénelubrifiants
la source
je copie votre expression rationnelle dans mon travail et le résultat est: quantificateur invalide + \]) [Break on this error] var filterdata = takedata.match (/ (\ [[^ \]] ++ \]) /); \ n ( firebugs + Firefox) quelque chose de mal?
Rueta
@Rueta: apparemment, la saveur Javascript ne prend pas en charge la possession. J'ai modifié ma réponse pour refléter ce fait. Vous pouvez simplement en utiliser un +au lieu de deux.
Lubrifiants polygéniques
1
Bien que les groupes atomiques puissent être utilisés à la place des quantificateurs possessifs, JavaScript ne prend pas non plus en charge les groupes atomiques. Mais il y a une troisième alternative, voyez ceci: instanceof.me/post/52245507631/… -you can emulate atomic grouping with LookAhead. (?>a) becomes (?=(a))\1
Roland Pihlakas
2
Ceci est une réponse Java pour une question JavaScript et Java! = JavaScript. Lecteurs, prenez note.
Roshambo
3

Je crois que ce serait comme ça

takedata.match(/(\[.+\])/g);

le gà la fin signifie global, donc il ne s'arrête pas au premier match.

iangraham
la source
oui, vous avez raison en / g. je viens de faire mon travail avec votre réponse / g ^^. Mais quand je fais régulièrement /(\\. + \\\) / mon résultat est: [| cơ thử | nghiệm |] thị trường [| test2 | đây là test lần 2 |] chứng khoán [| Mỹ | day la nuoc mon |] :(
Rueta