Quando una regexp non è un'espressione regolare?


9

Dal momento che sto studiando per il mio corso di lingue formale, mi sono imbattuto in questi post affascinanti ( One Two ) che descrivono come trovare un numero primo usando una regexp . Come ho detto, una regexp , non un'espressione regolare . Poiché un'espressione regolare può corrispondere a stringhe calcolate da un automa a stati finiti e la ricerca di un numero primo non può essere eseguita da un FSA, la regexp mostrata nel post del blog non è interamente un'espressione regolare poiché esegue il backtracking per abbinare la stringa.

Dato che non ho mai usato espressioni regolari, ora la mia domanda:

Come posso riconoscere immediatamente una regexp da un'espressione regolare "vera" solo guardandola?

Definizioni: per espressione regolare, mi riferisco al concetto definito nei linguaggi formali. Per regexp intendo l'idea supportata dai moderni linguaggi di programmazione; la sintassi regexp contiene spesso funzionalità aggiuntive, come i riferimenti indietro. I regexps visti nei linguaggi di programmazione sono strettamente più potenti delle espressioni regolari in stile linguistico formale.


5
Regexp è solo un'abbreviazione di espressione regolare. Il calcolo dei numeri primi si basa su un hack Perl, non su espressioni regolari.

1
È piuttosto semplice. Le lingue regolari impiegano concatenazione, ripetizione e alternanza. Ogni volta che un motore supporta qualcosa di non equivalente a questi, non è regolare.
Kilian Foth,

1
Domande correlate: 1 , 2 , 3 .
Raffaello

@Yannis Se salti oltre il recinto verso CS, non è più vero. I regexps visti nei linguaggi di programmazione sono strettamente più potenti delle espressioni regolari (stile di linguaggi formali) e la forma abbreviata "regexp" è per convenzione (non so quanto sia diffusa) usata per la prima, non per la seconda genere.
Raffaello

@KilianFoth Questa non è davvero una descrizione utile, però. Ad esempio, puoi aggiungere la negazione (o, in effetti, qualsiasi set finito di connettivi booleani) alle espressioni regolari senza aumentarne il potere.
David Richerby,

Risposte:


13

tl; dr backrefs.

Non appena c'è un \1(o qualsiasi numero che non è usato per sfuggire all'unicode) nella regexp non è un'espressione regolare.

Backrefs ti consente di abbinare le (a+)b\1corrispondenze n volte aseguite da b seguite da n volte aper qualsiasi n> 1. Questa non è una lingua normale (è il figlio del poster di una lingua non regolare).

È necessario e quasi sufficiente che il backref faccia riferimento a un gruppo che contiene una regexp che corrisponde a una stringa arbitrariamente lunga o che contiene un *o +. L'unica eccezione (che ho trovato) di una regexp della forma in (A)B\1cui A è un linguaggio finito (potrebbe essere sostituita da un elenco di tutte le parole che le accetta). Puoi convertirlo in word1+Bword1|word2+Bword2ecc. Perché A è finito.

I gruppi di ricerca non rimuovono la regolarità della regexp. A(?=B)Cè la sezione trasversale delle regex AB.*e ACla sezione trasversale di 2 lingue regolari è regolare. Lo sguardo negativo è simile tranne che per l'uso del complemento di B.*(i complementi delle lingue regolari sono regolari). Lookbehind è esattamente lo stesso anche A(?<=B)Cla sezione trasversale di ACe .*BC.


È necessario e sufficiente? Mi sembra che (a)\1, usando un backref, sia equivalente aae quindi banalmente regolare. Mi chiedo anche se le asserzioni lookahead possano usare per riconoscere lingue non regolari.
Saluti,

1
@MSalters: se vuoi diventare veramente tecnico, (a)\1non è un'espressione regolare, ma riconosce un linguaggio regolare.
Jörg W Mittag,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.