2012-02-19 12 views
21

En términos generales, quiero encontrar en la cadena algunas subcadenas, pero solo si está contenidas allí.Regex encuentra la palabra en la cadena

tuve la expresión:

^.*(\bpass\b)?.*$ 

Y prueba de la cuerda:

high pass h3 

Cuando pruebo la cadena a través de la expresión que veo esa cadena entera se encuentra (pero el grupo "pasan" No):

match : true 
groups count : 1 
group : high pass h3 

Pero que necesitaba, es que partido tiene 2 grupos: 1: paso alto h3 2: pasar

Y cuando pruebo, por ejemplo, la cadena - alta h3, todavía había encontrado 1 grupo - alta h3

¿Cómo puedo hacer esto?

+1

1. ¿En qué plataforma (no todas las implementaciones de expresiones regulares son los mismos): Perl, Python, Java, .NET, ...? 2. "solo si está contenido allí" no está claro. – Richard

+1

¿Por qué quieres la cadena completa como un partido? – Mat

+0

Podría ser multilínea, consiguiendo las líneas completas, incluida la palabra que se va a encontrar. – Mario

Respuesta

5

Le falta un poco para que funcione (además de que ? está en la posición incorrecta).

Si desea que coincida con la presencia frist: ^(.*?)(\bpass\b)(.*)$. Si quiere hacer coincidir la última ocurrencia: ^(.*)(\bpass\b)(.*?)$.

Esto dará como resultado 3 grupos de captura: Todo antes, la coincidencia exacta y todo lo siguiente.

. coincidirá (dependiendo de su configuración casi) con cualquier cosa, pero con un solo carácter. ? hará que el elemento precedente sea opcional, es decir, que no aparezca en absoluto o exactamente una vez. * coincidirá el elemento anterior varias veces, es decir, no en absoluto o una cantidad ilimitada de veces. Esto coincidirá con tantos caracteres como sea posible. Si combinas ambos en *? obtendrás una coincidencia desgregable, esencialmente combinando la menor cantidad de caracteres posible (hasta 0).

Editar: Al leer solo deseas pass y la cadena completa, dependiendo de la implementación/idioma, el siguiente debería ser suficiente: ^.*(\bpass\b).*?$ (de nuevo, el partido ungreedy podría ser intercambiado con el codicioso). Obtendrá la expresión/coincidencia completa como grupo 0 y la primera coincidencia definida como grupo 1.

+0

Desafortunadamente esta solución no funciona en C# regex, string - "high h3", mathces no encontrado en absoluto, pero esperaba que si la cadena no encontrada coincida debería devolver toda la cadena como un resultado de coincidencia. Lo que necesitaba es porque esta es la única parte de mi expresión de expresiones regulares y hay otros patrones para que funcione, incluso si no se encuentra el "pase". – baio

+0

Ah? "pasar" debe ser opcional? ¿Pensaste en definir secuencias alternativas usando '|'? P.ej. algo como '^. *? (\ b (?: passed | failed) \ b). *? $' coincidirá con ambas alternativas. ¿Por qué incluso tiene que coincidir con toda la línea, teniendo en cuenta que es lo que podría pasar? Puede hacer que cualquier secuencia sea opcional agregando '?', Pero esto podría tener un resultado inesperado al usar coincidencias de comodines que podrían incluir sus "palabras clave". – Mario

3

Un período sólo coincide con un solo carácter, por lo que está

^.(\bpass\b)?.$ 

está haciendo juego:

  • inicio de la entrada
  • un solo carácter
  • Opcionalmente
    • Palabra límite
    • "pasan"
    • límite de palabra
  • carbón individual
  • final de la entrada

la que yo no esperaría para que coincida con "h3 de paso alto" en absoluto.

La expresión regular:

pass 

(no hay meta-caracteres) coincidirá con cualquier cadena que contiene "pase" (pero también lo sería un "encontrar cadena en cadena" función, y esto probablemente sería más rápido sin la complejidad de una expresión regular).

43

Uso ésta:

^(.*?(\bpass\b)[^$]*)$ 
  1. primera captura para toda la línea.
  2. Segunda captura de la palabra esperada.

Compruebe demo.

Más explicación:

  ┌ first capture 
      | 
⧽------------------⧼ 
^(.*?(\bpass\b)[^$]*)$ 
    ⧽-⧼   ⧽---⧼ 
    | ⧽--------⧼ | 
    |  |  └ all characters who are not the end of the string 
    |  | 
    |  └ second capture 
    | 
    └ optional begin characters 
+0

Thansks! Pero el problema es lo que necesitaba para encontrar la coincidencia (texto completo), incluso si "pase" no está en la cadena probada. Consulte su demostración. ¿Es posible? – baio

+0

Verifique este: http://www.myregextester.com/?r=aa94f52d '^ (. *? (\ Bpass \ b) [^ $] * | [^ $] *) $' – piouPiouM

Cuestiones relacionadas