2010-01-06 20 views
216

Estoy buscando un patrón que coincida con todo hasta la primera aparición de un personaje específico, digamos un ";" - punto y coma.Regex: coincidiendo con la primera aparición de un personaje

me escribió esto:

/^(.*);/ 

Pero en realidad coincide con todo (incluyendo el punto y coma) hasta que la última aparición de un punto y coma.

+40

'' /^(.*?);/ también deben trabajar (se llama ** ** no expansivo), pero las respuestas dadas usando '[^;] *' son mejores. – Pascal

+0

cómo seleccionaría todo, después del punto y coma, y ​​no el punto y coma en sí. –

+0

ver esto funciona '\ w + (?! ([^] +;) |;)' Pero esto no significa por qué? '. + (?! ([^] +;) |;)' –

Respuesta

326

Usted necesita

/[^;]*/ 

El [^;] es una clase de caracteres , que coincide con todo menos un punto y coma.

Para citar la página de manual perlre:

Puede especificar una clase de caracteres, encerrando una lista de caracteres en [], que coincidirá con cualquier carácter de la lista. Si el primer carácter después de "[" es "^", la clase coincide con cualquier personaje que no esté en la lista.

Esto debería funcionar en la mayoría de los dialectos de expresiones regulares.

14

Trate /[^;]*/

Google regex character classes para más detalles.

30

/^[^;]*/

El [^;] dice que coincida con nada excepto un punto y coma. Los corchetes son un operador de coincidencia de conjuntos, esencialmente, coincide con cualquier carácter de este conjunto de caracteres, el ^ al comienzo lo convierte en una coincidencia inversa, por lo que debe coincidir con cualquier elemento que no sea en este conjunto.

+2

Tenga en cuenta que el primero^en esta respuesta le da a la expresión regular un significado completamente diferente: hace que la expresión regular se vea solo para las coincidencias comenzando desde el comienzo de la cadena. En este caso, eso sería efectivamente un no * op * si * ejecuta la expresión regular solo una vez. Si quiere buscar múltiples coincidencias dentro de una sola cadena, la primera^tendría que irse. –

+3

Dijo que quería hacer coincidir todo hasta la primera aparición de un punto y coma, así que supuse que quería decir desde el principio de la cadena. –

184

Would;

/^(.*?);/ 

trabajo?

El ? es un operador flojo, por lo que la expresión regular toma lo menos posible antes de coincidir con el ;.

+3

Sí, recuerda que TMTOWTDI es una moto perl :) http://en.wikipedia.org/wiki/TMTOWTDI –

+3

ya, pero siguiendo la extensión de bicarbonato de Tim Toady, creo que las clases de personajes negadas ganan como un cuantificador vago incluye el back-back. +1 de todos modos. – Amarghosh

+2

Merece la pena leer sobre el tema de rendimiento: http://blog.stevenlevithan.com/archives/greedy-lazy-performance –

5

esto no es una solución de expresiones regulares, pero algo bastante simple para la descripción de su problema. Solo divide tu cadena y obtén el primer elemento de tu matriz.

$str = "match everything until first ; blah ; blah end "; 
$s = explode(";",$str,2); 
print $s[0]; 

salida

$ php test.php 
match everything until first 
4

Esto fue muy útil para mí como yo estaba tratando de averiguar cómo hacer coincidir todos los caracteres en una etiqueta XML que incluye atributos.Yo estaba corriendo en el "coincide con todo para el final" problema:

/<simpleChoice.*>/ 

pero fue capaz de resolver el problema con:

/<simpleChoice[^>]*>/ 

después de leer este post. Gracias a todos.

+0

Descubrí que es mucho más eficiente analizar realmente (cada idioma o marco tiene sus propias clases para eso) html/xml debido a su formato de máquina, las expresiones regulares son para lenguaje natural. –

+0

Agradable. Lo usé para corregir documentos xml con errores de sintaxis en la etiqueta ''. Dado que el analizador no fue capaz de manejarlo. –

5
texto

muestra:

"this is a test sentence; to prove this regex; that is g;iven below" 

Si por ejemplo tenemos el texto de ejemplo anterior, la expresión regular /(.*?\;)/ le dará todo hasta la primera aparición de punto y coma (;), incluyendo el punto y coma: "this is a test sentence;"

+1

no es necesario escapar ';' char porque no es un caracter especial de expresiones regulares. La agrupación '()' no es necesaria también. Puede ir con '/.*?;/' –

+0

sí, tiene toda la razón. el escape fue más como "mejor prevenir que lamentar" – poncius

+1

Esta es la respuesta que estaba buscando. Entonces el ? hace que el partido termine en la primera ocurrencia? ¿Cuál es el nombre de esta ... (llamémosla) propiedad de la expresión regular? – Parziphal

3

"/^([^\/]*)\/$/" trabajó para mí, para obtener sólo la parte superior "carpetas" de una matriz como:

a/ <- this 
a/b/ 
c/ <- this 
c/d/ 
/d/e/ 
f/ <- this 
2

Realmente es un poco triste que nadie te haya dado la respuesta correcta ...

In regex,? lo hace no codicioso. De forma predeterminada, la expresión regular coincidirá tanto como pueda (codicioso)

Simplemente agregue un? y será no codicioso y coincidirá lo menos posible.

Buena suerte, espero que ayude.

+2

Esto depende en gran medida de la implementación real ** de expresiones regulares y no todas las implementaciones tienen un modo no codicioso. – karatedog

1

Esto coincidirá con la primera ocurrencia solamente en cada cadena e ignorará las ocurrencias subsiguientes.

/^([^;]*);*/ 
Cuestiones relacionadas