Regex: coincidencia con la primera aparición de un personaje

358

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

Yo escribí esto:

/^(.*);/

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

Leon Fedotov
fuente
65
/^(.*?);/también debería funcionar (se llama no codicioso ), pero las respuestas dadas usando [^;]*son mejores.
Pascal
¿Cómo seleccionaría todo, después del punto y coma, y ​​no el punto y coma en sí?
Muhammad Umer
ves esto funciona \w+(?!([^]+;)|;)pero esto no es por qué? .+(?!([^]+;)|;)
Muhammad Umer
1
¡Pascal, deberías haber escrito eso como respuesta!
Sean Kendle
@Pascal ¡Esto es adecuado como respuesta! ¡Gracias!
neverMind9

Respuestas:

503

Necesitas

/[^;]*/

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

Para citar la página de perlremanual:

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 carácter que no esté en la lista.

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

sleske
fuente
La gran parte de esta solución es que también coincide con el final de la línea, por ejemplo, en mi caso lo hice foo=bar;baz=bax;bab=bafy coincidió bab=bafincluso si no hay ;exactamente lo que necesito. No estoy seguro de por qué funciona, aunque si dice especificación partidos todo, pero el símbolo de blanco ...
skryvets
303

Haría;

/^(.*?);/

¿trabajo?

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

RJFalconer
fuente
44
sí, pero después de la extensión de bicarbonato a Tim Toady, creo que las clases de caracteres negadas ganan ya que el cuantificador perezoso incluye retroceso. +1 de todos modos.
Amarghosh
3
Vale la pena leer sobre el tema del rendimiento: blog.stevenlevithan.com/archives/greedy-lazy-performance
Glenn Slaven
38

/^[^;]*/

El [^;] dice unir cualquier cosa excepto un punto y coma. Los corchetes son un operador de coincidencia de conjunto, esencialmente, coincide con cualquier carácter de este conjunto de caracteres, ^al principio lo convierte en una coincidencia inversa, por lo que coincide con cualquier cosa que no esté en este conjunto.

Glenn Slaven
fuente
3
Tenga en cuenta que el primer ^ en esta respuesta le da a la expresión regular un significado completamente diferente: hace que la expresión regular busque solo coincidencias que comiencen desde el comienzo de la cadena. En este caso, eso sería efectivamente no operativo si ejecuta la expresión regular solo una vez. Si desea buscar múltiples coincidencias dentro de una sola cadena, la primera ^ tendría que irse.
Dan Breslau
44
Dijo que quería unir todo hasta la primera aparición de un punto y coma, así que supuse que se refería desde el principio de la cadena.
Glenn Slaven el
15

Tratar /[^;]*/

Google regex character classespara más detalles.

Dan Breslau
fuente
8

texto de ejemplo:

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

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

poncius
fuente
3
no es necesario escapar del ;carbón porque no es un carácter especial regex. La agrupación ()tampoco es necesaria. Usted puede ir con/.*?;/
Aliaksei Kliuchnikau
1
Sí, tienes toda la razón. la fuga fue más como "más
vale
2
Esta es la respuesta que estaba buscando. Entonces el ? hace que el partido termine en el primer caso? ¿Cuál es el nombre de esta propiedad ... (llamémosla) de la expresión regular?
Parziphal
1
@Parziphal, el ?personaje hace que la partida sea perezosa (coincida la menor cantidad posible) Piense en los caracteres coincidentes de expresiones regulares hasta el primer punto y coma, luego no va más allá porque se da por vencido (perezoso;))
derekantrican
5

Esta no es una solución de expresiones regulares, sino algo bastante simple para la descripción del problema. Simplemente divida su cadena y obtenga el primer elemento de su matriz.

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

salida

$ php test.php
match everything until first
ghostdog74
fuente
5

Esto fue muy útil para mí, ya que estaba tratando de descubrir cómo hacer coincidir todos los caracteres en una etiqueta xml, incluidos los atributos. Me encontraba con el problema de "coincide todo hasta el final" con:

/<simpleChoice.*>/

pero pude resolver el problema con:

/<simpleChoice[^>]*>/

Después de leer esta publicación. Gracias a todos.

Yardboy
fuente
1
Descubrí que es mucho más eficiente analizar realmente (cada lenguaje o marco tiene sus propias clases para eso) html / xml debido a su formato de máquina, las expresiones regulares son para lenguaje natural.
Leon Fedotov
1
Agradable. Utilicé esto para arreglar documentos xml con errores de sintaxis en la <!DOCTYPE>etiqueta. Como el analizador no fue capaz de manejarlo.
Martin Schneider
5

Esto coincidirá con la primera aparición solo en cada cadena e ignorará las siguientes.

/^([^;]*);*/
mchid
fuente
3

"/^([^\/]*)\/$/" funcionó para mí, para obtener solo las "carpetas" superiores de una matriz como:

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

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

En regex,? lo hace no codicioso. Por defecto, la expresión regular coincidirá tanto como sea posible (codicioso)

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

Buena suerte, espero que ayude.

L1amm
fuente
3
Esto depende en gran medida de la implementación real de expresiones regulares y no todas las implementaciones tienen modo no codicioso.
karatedog
0

encontre eso

/^[^,]*,/

funciona bien.

',' siendo el "delimitador" aquí.

BookerVII
fuente