¿Cuándo es una expresión regular no es una expresión regular?

9

Como estoy estudiando para mi curso universitario de idiomas formales, me topé con estas fascinantes publicaciones ( One Two ) que describen cómo encontrar un número primo usando una expresión regular . Como ya he dicho, una expresión regular , no una expresión regular . Dado que una expresión regular puede coincidir con cadenas calculadas por Autómatas de estado finito y una FSA no puede encontrar un número primo, la expresión regular que se muestra en la publicación del blog no es del todo una expresión regular, ya que hace un retroceso para coincidir con la cadena.

Como nunca he usado realmente ninguna expresión regular, ahora, mi pregunta:

¿Cómo puedo reconocer inmediatamente una expresión regular de una expresión regular "verdadera" con solo mirarla?

Definiciones: Por expresión regular, me refiero a la noción como se define en los lenguajes formales. Por regexp, me refiero a la noción soportada por los lenguajes de programación modernos; la sintaxis regexp a menudo contiene características adicionales, como referencias posteriores. Las expresiones regulares como se ve en los lenguajes de programación son estrictamente más poderosas que las expresiones regulares de estilo de lenguajes formales.

peperunas
fuente
55
Regexp es solo una abreviatura de expresión regular. El cálculo de números primos se basa en un hack de Perl, no en expresiones regulares.
1
Es bastante simple. Los idiomas regulares emplean concatenación, repetición y alternancia. Cada vez que un motor admite algo no equivalente a estos, no es regular.
Kilian Foth
1
Preguntas relacionadas: 1 , 2 , 3 .
Raphael
@ Yannis Si saltas la valla a CS, eso ya no es cierto. Las expresiones regulares, como se ve en los lenguajes de programación, son estrictamente más poderosas que las expresiones regulares (estilo de lenguajes formales), y la forma abreviada "regexp" es por convención (no sé cuán extendido es) utilizada para la primera, no para la segunda. tipo.
Raphael
@KilianFoth Sin embargo, esa no es realmente una descripción útil. Por ejemplo, puede agregar negación (o, de hecho, cualquier conjunto finito de conectivos booleanos) a expresiones regulares sin aumentar su poder.
David Richerby

Respuestas:

13

tl; dr backrefs.

Tan pronto como haya un \1(o cualquier número que no se use para escapar de Unicode) en la expresión regular, no es una expresión regular.

Backrefs le permite hacer coincidir (a+)b\1qué coincide n veces aseguido de b seguido de n veces apara cualquier n> 1. Este no es un idioma regular (es el póster hijo de un idioma no regular).

Es necesario y casi suficiente que la referencia de referencia haga referencia a un grupo que contiene una expresión regular que coincide con una cadena arbitrariamente larga o que contiene una *o +. La única excepción (que encontré) de una expresión regular de la forma (A)B\1en la que A es un lenguaje finito (podría reemplazarse por una enumeración de todas las palabras que las acepta). Puede convertirlo a word1+Bword1|word2+Bword2etc. porque A es finito.

Los grupos de búsqueda no eliminan la regularidad de la expresión regular. A(?=B)Ces la sección transversal de las expresiones regulares AB.*y ACla sección transversal de 2 idiomas regulares es regular. La búsqueda anticipada negativa es similar, excepto que utiliza el complemento de B.*(los complementos de los idiomas regulares son regulares). Mirar hacia atrás es exactamente igual, así como A(?<=B)Cla sección transversal de ACy .*BC.

monstruo de trinquete
fuente
¿Es esto necesario y suficiente? Me parece que (a)\1, mientras usa un reflujo, es equivalente aay, por lo tanto, trivialmente regular. También me pregunto si las aserciones anticipadas pueden usarse para reconocer lenguajes no regulares.
MSalters
1
@MSalters: si quieres ser realmente técnico, (a)\1no es una expresión regular, pero reconoce un lenguaje regular.
Jörg W Mittag