¿Cómo convertir la expresión regular en no codiciosa?

227

Estoy usando jQuery. Tengo una cadena con un bloque de caracteres especiales (principio y fin). Quiero obtener el texto de ese bloque de caracteres especiales. Usé un objeto de expresión regular para encontrar en cadena. Pero, ¿cómo puedo decirle a jQuery que busque múltiples resultados cuando tenga dos caracteres especiales o más?

Mi 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>

y mi código JavaScript:

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

  alert(filterdata); 

  //end write js 
});

Mi resultado es: [| cơ thử | nghiệm |] thị trường [| test2 | đây là test lần 2 |] chứng khoán [| Mỹ | day la nuoc my |] . Pero este no es el resultado que quiero :(. ¿Cómo obtener [texto] para los tiempos 1 y [demo] para los tiempos 2?


Acabo de hacer mi trabajo después de buscar información en internet ^^. Hago un código como este:

var filterdata = takedata.match(/(\[.*?\])/g);
  • mi resultado es: [| cơ thử | nghiệm |], [| test2 | đây là test lần 2 |] ¡ esto es correcto !. pero realmente no entiendo esto. ¿Puedes responder mi por qué?
Rueta
fuente

Respuestas:

492

Los modificadores de expresiones regulares no codiciosos son como sus contrapartes codiciosos pero con un ?seguimiento inmediato de ellos:

*  - 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
fuente
29
podría ser útil tener en cuenta que ?por sí solo significa 'uno o cero' (¡pero es codicioso!). Por ejemplo 'bb'.replace(/b?/, 'a') //'ab'y'bb'.replace(/c?/, 'a') //'abb'
Hashbrown
1
¿Cómo no coincidió nada allí?
Muhammad Umer
1
@MuhammadUmer Creo que estaba sugiriendo eso porque cno coincidirá, pero usted tiene el ?, que es 0 or 1, entonces coincidirá 0 number of c characters, por lo tanto, lo reemplazará. Sin embargo, no tengo idea de cómo funciona, porque eso no se compila en ningún motor regex que he probado 😢
Noctis
35

Tienes razón en que la codicia es un problema:

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

Si quieres unir ambos A--Z, deberías usar A.*?Z(lo que ?hace que sea *"reacio" o perezoso).

Sin embargo, a veces hay mejores maneras de hacer esto, p. Ej.

A[^Z]*+Z

Utiliza una clase de caracteres negada y un cuantificador posesivo para reducir el retroceso y es probable que sea más eficiente.

En su caso, la expresión regular sería:

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

Desafortunadamente, Javascript regex no admite cuantificador posesivo, por lo que solo tendría que ver con:

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

Ver también


Sumario rápido

*   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

Tenga en cuenta que los cuantificadores reacios y posesivos también son aplicables a las {n,m}construcciones de repetición finita .

Ejemplos 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"
poligenelubricantes
fuente
Copio su expresión regular en mi trabajo y el resultado es: cuantificador inválido + \]) [Romper en este error] var filterdata = takedata.match (/ (\ [[^ \]] ++ \]) /); \ n ( Firebugs + Firefox) algo mal?
Rueta
@Rueta: aparentemente el sabor de Javascript no es compatible con posesivo. He editado mi respuesta para reflejar este hecho. Puedes usar uno en +lugar de dos.
Polygenelubricants
1
Aunque los grupos atómicos se pueden usar en lugar de cuantificadores posesivos, JavaScript tampoco admite los grupos atómicos. Pero hay una tercera alternativa, vea esto: instanceof.me/post/52245507631/… -you can emulate atomic grouping with LookAhead. (?>a) becomes (?=(a))\1
Roland Pihlakas
2
Esta es una respuesta de Java para una pregunta de JavaScript y Java! = JavaScript. Lectores, tomen nota.
Roshambo
3

Creo que seria asi

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

el gal final significa mundial, por lo que no se detiene en el primer partido.

iangraham
fuente
sí, tienes razón en / g. Acabo de hacer mi trabajo con tu respuesta / g ^^. Pero cuando hago /(\[.+\font>)/g regular mi resultado es: [| cơ thử | nghiệm |] thị trường [| test2 | đây là test lần 2 |] chứng khoán [| Mỹ | day la nuoc my |] :(
Rueta