¿Cómo hacer una copia de seguridad de las selecciones “internas” de referencia (()) en una expresión regular?

¿Cómo respaldas el paréntesis interno de referencia en Regex?

Los datos de muestra son una lista de precios de productos que muestra diferentes descuentos de precios en función de la cantidad comprada. El formato es quantityLow – quantityHigh: pricePer; múltiplos.

Usé LINQPad para construir esta expresión Regex C # para separar las partes, lo que muestra una visualización útil de la separación de datos Regex. En este ejemplo, hay paréntesis “internos” (selecciones), creando una estructura de datos jerárquica.

string mys = "1-4:2;5-9:1.89"; Regex.Matches (mys, @"((\d+)[-|\+](\d*):(\d+\.?\d*);?)").Dump(); // Graphically show 

Esto se divide en (El partido es todo. Dentro del partido, hay un solo partido y un partido de grupo. Dentro del partido de grupo hay unas pocas coincidencias).

  • MatchCollection (2 artículos)
    • Colección grupal (4 artículos)
      • CaptureCollection (1 artículo) () Grupo “1-4: 2;”
      • CaptureCollection (1 artículo) () Grupo “1”
      • CaptureCollection (1 item) () Group “4”
      • CaptureCollection (1 artículo) () Grupo “2”
    • CaptureCollection (1 artículo) () Match “1-4; 2;”
    • Colección grupal (4 artículos)
      • CaptureCollection (1 item) () Grupo “5-9: 1.89”
      • CaptureCollection (1 item) () Grupo “5”
      • CaptureCollection (1 item) () Grupo “9”
      • CaptureCollection (1 artículo) () Grupo “1.89”
    • CaptureCollection (1 artículo) () Match “5-9: 1.89”

Solo para referencia:

  • () el grupo de paréntesis encontró resultados que pueden ser referenciados por un \ 1 .. \ 9 (creo).
  • \ d coincide con un solo dígito. El + después coincide con uno o más dígitos. * después de coincide con cero o más dígitos. ? after dice que este partido es opcional.
  • . coincide con un solo personaje. \. coincide con un punto o decimal en este caso.

Simplemente use \1\9 (o $1$9 en algunas implementaciones de expresiones regulares) como lo haría normalmente. La numeración es de izquierda a derecha, en función de la posición del paréntesis abierto (por lo que un grupo nested tiene un número más alto que el grupo (s) en el que está nested).

Tenga en cuenta que esto es en respuesta al comentario del Dr. Zim:

“Curiosamente, ambas formas parecen funcionar bien. Cogí” Regulator “, que al menos muestra cómo se descomponen las expresiones regulares. Si tiene una función para establecer la implementación, creo que estoy en el negocio”.

pero mi respuesta fue demasiado larga para el cuadro de comentarios.

No, no necesita escapar del más, y en este caso el guión. Dentro de una clase de personaje, los siguientes caracteres tienen un significado especial: ] , ^ y - . Estos tres personajes son los únicos personajes que pueden necesitar escaparse (tenga en cuenta que [ no necesita escaparse]). Digo poder porque depende de dónde se producen estos metacaracteres. El ^ solo tiene un significado especial (como un indicador de negación ) cuando se coloca al comienzo de una clase de caracteres, en otro lugar, no necesita escaparse y coincidirá solo con el literal ^ . Algunos ejemplos para ilustrar:

 [^a] // special meaning: matches any character except 'a' [a^] // matches 'a' or '^' [\^a] // matches '^' or 'a' 

Y el guión solo tiene un significado especial (como un indicador de rango ) cuando se coloca no al principio o al final de una clase de caracteres. Ejemplos:

 [ac] // special meaning: matches 'a', 'b' or 'c' [ac-] // matches 'a', 'c' or '-' [-ac] // matches '-', 'a' or 'c' [a\-c] // matches 'a', '-' or 'c' 

Sin lugar a dudas, algunas implementaciones de expresiones regulares podrían diferir de las que acabo de publicar, pero la mayoría de los idiomas cumplirán con estas reglas (¡todos los idiomas con los que trabajé al menos!). Y como habrás notado, es seguro sobrepasar caracteres dentro de las clases de caracteres: no hace ningún daño. Ambas clases [+] y [\+] coincidirán con el literal + . En mi humilde opinión, el primero es preferido porque encuentro una expresión regular con demasiados escapes difíciles de leer. Pero algunos estarán en desacuerdo conmigo y descubrirán que es más claro al usar un escape (aunque no es necesario) que el literal + se esté emparejando en lugar del codificador cuantificador.

Espero que eso aclare las cosas.

Como nota al margen, las clases de caracteres siempre coinciden con un solo carácter y los metacaracteres “normales” no se aplican en ellos. Entonces tu clase [-|\+] coincide con uno de los tres caracteres - , | o + . Como puede ver, el carácter lógico OR meta no tiene un significado especial dentro de una clase de personaje. Y no necesita escapar del carácter + dentro de una clase de personaje, así que esto debería hacerlo: [-+] .