Pregunta

En mi OS X 10.5.8 de la máquina, utilizando la regcomp y regexec funciones de C para que coincida con la expresión regular extendida "(()|abc)xyz", me parece un partido para la cadena "abcxyz" pero sólo a partir de desplazamiento de 3 a desplazamiento de 6.Mi expectativa era que toda la cadena se emparejados y que me gustaría ver un submatch para la inicial de "abc" parte de la cadena.

Cuando me pruebe el mismo patrón y el texto con awk en la misma máquina, se muestra un partido para toda la cadena como cabría esperar.

Espero que mi limitada experiencia con expresiones regulares puede ser el problema.Puede alguien explicar lo que está pasando?Es mi expresión regular válida?Si es así, ¿por qué no coinciden con la totalidad de la cadena?

Entiendo que "((abc){0,1})xyz" podría ser utilizada como una alternativa, pero el patrón de interés que se genera automáticamente a partir de otro formato de trama y la eliminación de instancias de "()" es un trabajo extra que me gustaría evitar, si es posible.

Para referencia, las banderas, estoy pasando a regcomp sólo consisten en REG_EXTENDED.Yo pase de un conjunto vacío de banderas (0) a regexec.

¿Fue útil?

Solución

El POSIX norma dice:

9.4.3 ERE Caracteres Especiales

Un ERE de carácter especial tiene propiedades especiales en ciertos contextos.Fuera de esos contextos, o cuando es precedida por una <backslash>, un personaje será un ERE que coincide con el carácter especial de sí mismo.Las expresiones regulares extendidas de los caracteres especiales y los contextos en los que tienen su significado especial es la siguiente:

.[\(

El <period>, <left-square-bracket>, <backslash>, y <left-parenthesis> será de especial excepto cuando se utiliza en un soporte de expresión (ver RE Soporte de la Expresión ).Fuera de un soporte de expresión, una <left-parenthesis> inmediatamente seguido por un <right-parenthesis> produce resultados indefinidos.

Lo que estamos viendo es el resultado de la invocación de un comportamiento indefinido - nada va.

Si desea confiable, portátil resultados, tendrás que eliminar el vacío"()'notaciones.

Otros consejos

Si iteras sobre todas las coincidencias y no obtienes tanto [3,6) como [0,6), entonces hay un error. No estoy seguro de qué manda Posix en cuanto al orden en que se devuelven las coincidencias.

Prueba (abc|())xyz - Apuesto a que producirá el mismo resultado en ambos lugares. Solo puedo suponer que la versión C intenta hacer coincidir xyz donde sea posible, y si eso falla, intenta hacer coincidir abcxyz donde sea posible (pero, como puede ver, no falla, por lo que nunca molesta con la parte " abc " mientras que awk debe estar usando su propio motor de expresiones regulares que funciona de la manera que esperas.

Su expresión regular es válida. Creo que el problema es a) POSIX no tiene muy claro cómo debería funcionar la expresión regular, o b) <=> no está utilizando expresiones regulares 100% compatibles con POSIX (probablemente porque parece que OS X se entrega con una versión más original) de <=>). Cualquiera que sea el problema, probablemente se deba a que este es un caso de borde y la mayoría de la gente no escribiría la expresión regular de esa manera.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top