Prevenir la parte no codicioso de consumir la siguiente parte opcional

Marcos Jeronimus:

Tengo una expresión regular con una parte obligatoria, un (? Perezoso) parte no codicioso, una parte opcional y, finalmente, otra parte no codicioso.

<mandatory><non-greedy><optional><non-greedy>
Implementado como:
^mandatory.*?(:?optionalpart)?.*?$

El optionalpart consiste en 'una pieza de encontrar' y 'una pieza de volver en un grupo de captura'.

^mandatory.*?(:?findme(matchme))?.*?$

Pero para algunas entradas de la primera parte Consume caracteres que no sean codiciosos que la siguiente parte opcional deben coincidir. ¿Hay una manera de hacer la parte opcional más codiciosos que la parte anterior no expansivo?


Ejemplo: Encontrar el personaje después de que el 2,, o encontrar una cadena vacía si no hay 2,, pero las coincidencias parte obligatoria.

"Foo: 2,b,1,a,3,c" -> match, $1 = "b"
"Foo: 1,a,2,b,3,c" -> match, $1 = "b"
"Foo: 1,a,3,c,2,b" -> match, $1 = "b"
"Foo: 2,b"         -> match, $1 = "b"
"Foo: 1,a,3,c"     -> match, $1 = ""
"Fuu: 1,a,2,b,3,c" -> no match.

Remate 1: ^Foo: .*?(?:2,([a-z]))?.*?$
Se produce un error en la segunda y tercera ejemplo, volviendo ""en lugar de "2".

Intento 2: ^Foo: .*?(?:2,([a-z])).*?$
esto soluciona falla la anterior, pero ahora falla en el quinto ejemplo, que no se ajuste.
La parte que debe ser opcional ya no es opcional.

Si importa, estoy usando la clase del patrón de Java.

-

Esto fue preguntado antes , pero no había ninguna respuesta satisfactoria para ninguno de nosotros.

Wiktor Stribiżav:

Su primera expresión regular está muy cerca, tiene que mover (?:un poco más a la izquierda para incluir el .*?patrón:

^Foo:(?: .*?2,([a-z]))?.*$
     ^^^ 

Vea la demostración de expresiones regulares

detalles

  • ^ - comenzar de cuerda
  • Foo: - un texto literal
  • (?: .*?2,([a-z]))?- un grupo opcional no captura que partidos avidez (se trataron al menos una vez) 1 o 0 ocurrencias de:
    • .*? - espacio siguió con cualquier 0+ caracteres distintos de los caracteres de salto de línea, el menor número posible
    • 2, - una subcadena literal
    • ([a-z]) - Grupo 1: una letra minúscula
  • .* - cualquier 0+ caracteres distintos de los caracteres de salto de línea (el resto de la cadena)
  • $ - final de la cadena.

El patrón general se parecerá

^<MANADATORY_LITERAL>(?:<NON_GREEDY_DOT>(<OPTIONAL_PART>))?<GREEDY_DOT>$

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=218122&siteId=1
Recomendado
Clasificación