Perché le espressioni regolari non possono utilizzare parole chiave anziché caratteri?

StackOverflow https://stackoverflow.com/questions/629573

  •  08-07-2019
  •  | 
  •  

Domanda

Ok, capisco a malapena le basi di RegEx, ma perché non potrebbero progettarlo per utilizzare parole chiave (come SQL) invece di alcuni caratteri jolly e simboli criptici?

È per le prestazioni poiché RegEx viene interpretato/analizzato in fase di esecuzione?(non compilato)

O forse per la velocità di scrittura?Considerando che quando impari alcune combinazioni di caratteri "semplici" diventa più semplice digitare 1 carattere invece che una parola chiave?

È stato utile?

Soluzione

Vuoi davvero questo ?

Pattern findGamesPattern = Pattern.With.Literal(@"<div")
    .WhiteSpace.Repeat.ZeroOrMore
    .Literal(@"class=""game""").WhiteSpace.Repeat.ZeroOrMore.Literal(@"id=""")
    .NamedGroup("gameId", Pattern.With.Digit.Repeat.OneOrMore)
    .Literal(@"-game""")
    .NamedGroup("content", Pattern.With.Anything.Repeat.Lazy.ZeroOrMore)
    .Literal(@"<!--gameStatus")
    .WhiteSpace.Repeat.ZeroOrMore.Literal("=").WhiteSpace.Repeat.ZeroOrMore
    .NamedGroup("gameState", Pattern.With.Digit.Repeat.OneOrMore)
    .Literal("-->");

Ok, ma è il tuo funerale , amico.

Scarica la libreria che fa questo qui:
http://flimflan.com/blog/ReadableRegularExpressions.aspx

Altri suggerimenti

Le espressioni regolari hanno un background matematico (in realtà, teoria del linguaggio) e sono codificate in qualche modo come una formula matematica . Puoi definirli in base a una serie di regole, ad esempio

  • ogni personaggio è un'espressione regolare, che rappresenta se stesso
  • se a e b sono espressioni regolari, quindi a?, a|b e ab sono anche espressioni regolari
  • ...

L'uso di un linguaggio basato su parole chiave sarebbe un grande onere per semplici espressioni regolari. Il più delle volte, userete semplicemente una semplice stringa di testo come modello di ricerca:

grep -R 'main' *.c

O forse schemi molto semplici:

grep -c ':-[)(]' seidl.txt

Una volta abituati alle espressioni regolari, questa sintassi è molto chiara e precisa. In situazioni più complicate probabilmente userete qualcos'altro poiché una grande espressione regolare è ovviamente difficile da leggere.

Perl 6 sta facendo un passo piuttosto rivoluzionario nella leggibilità della regex. Prendi in considerazione un indirizzo del modulo: 100 E Main St Springfield MA 01234

Ecco una regex compatibile con Perl 5 leggibile moderatamente per analizzarla (molti casi angolari non gestiti):

 m/
     ([1-9]\d*)\s+
     ((?:N|S|E|W)\s+)?
     (\w+(?:\s+\w+)*)\s+
     (ave|ln|st|rd)\s+
     ([:alpha:]+(?:\s+[:alpha:]+)*)\s+
     ([A-Z]{2})\s+
     (\d{5}(?:-\d{4})?)
  /ix;

Questa regex di Perl 6 ha lo stesso comportamento:

grammar USMailAddress {
     rule  TOP { <addr> <city> <state> <zip> }

     rule  addr { <[1..9]>\d* <direction>?
                  <streetname> <streettype> }
     token direction { N | S | E | W }
     token streetname { \w+ [ \s+ \w+ ]* }
     token streettype {:i ave | ln | rd | st }
     token city { <alpha> [ \s+ <alpha> ]* }
     token state { <[A..Z]>**{2} }
     token zip { \d**{5} [ - \d**{4} ]? }
  }

Una grammatica Perl 6 è una classe e i token sono tutti metodi invocabili. Usalo in questo modo:

if $addr ~~ m/^<USMailAddress::TOP>$/ {
     say "$<city>, $<state>";
}

Questo esempio deriva da un che ho presentato al Frozen Perl 2009 . L'implementazione di Rakudo di Perl 6 è abbastanza completa che questo esempio funziona oggi.

Bene, se avessi parole chiave, come le distingueresti facilmente dal testo effettivamente abbinato? Come gestiresti gli spazi bianchi?

Testo sorgente Azienda: A Dipartimento: B

Regex standard:

Company:\s+(.+)\s+Dept.:\s+(.+)

O anche:

Company: (.+) Dept. (.+)

Parola chiave regex (cercando davvero di non ottenere un uomo di paglia ...)

"Company:" whitespace.oneplus group(any.oneplus) whitespace.oneplus "Dept.:" whitespace.oneplus group(any.oneplus)

O semplificato:

"Company:" space group(any.oneplus) space "Dept.:" space group(any.oneplus)

No, probabilmente non è meglio.

Perché corrisponde alla teoria del linguaggio formale e alla sua notazione matematica.

È colpa di Perl ...!

In realtà, più specificamente, le espressioni regolari provengono dal primo sviluppo di Unix e la sintassi sintetica era molto più apprezzata allora. Lo spazio di archiviazione, i tempi di elaborazione, i terminali fisici, ecc. Erano tutti molto limitati, piuttosto diversamente da oggi.

La storia delle espressioni regolari su Wikipedia spiega di più.

Esistono alternative a Regex, ma non sono sicuro che ne abbiano davvero preso piede.

EDIT: corretto da John Saunders: le espressioni regolari sono state rese popolari da Unix, ma prima implementate da QED . Gli stessi vincoli di progettazione si applicavano, ancor più, ai sistemi precedenti.

In realtà no, il mondo non è iniziato con Unix. Se leggi l'articolo di Wikipedia, lo vedrai

  

Negli anni '50, il matematico Stephen Cole Kleene descrisse questi modelli usando la sua notazione matematica chiamata set regolari. Il linguaggio SNOBOL era un'implementazione iniziale della corrispondenza dei modelli, ma non identica alle espressioni regolari. Ken Thompson ha incorporato la notazione di Kleene nell'editor QED come mezzo per abbinare i pattern nei file di testo. In seguito ha aggiunto questa funzionalità al redattore di Unix, che alla fine ha portato al popolare strumento di ricerca utilizzato da grep per le espressioni regolari

Questo è molto prima di PERL. La voce di Wikipedia sulle espressioni regolari attribuisce le prime implementazioni delle espressioni regolari a Ken Thompson di UNIX fama, che li ha implementati nel QED e poi nell'editor ed . Immagino che i comandi avessero nomi brevi per motivi di prestazioni, ma molto prima di essere lato client. Padroneggiare le espressioni regolari è un ottimo libro sulle espressioni regolari, che offre la possibilità di annotare un'espressione regolare (con il simbolo / x flag) per facilitare la lettura e la comprensione.

Perché l'idea delle espressioni regolari - come molte cose che hanno origine da UNIX - è che sono concise, favorendo la brevità sulla leggibilità. Questa è in realtà una buona cosa. Ho finito per scrivere espressioni regolari (contro il mio miglior giudizio) lunghe 15 righe. Se ciò avesse una sintassi dettagliata non sarebbe una regex, sarebbe un programma.

In realtà è abbastanza facile implementare un " wordier " forma di regex - vedi la mia risposta qui . In breve: scrivere una manciata di funzioni che restituiscono stringhe regex (e accettano parametri se necessario).

Non credo che le parole chiave possano dare alcun vantaggio. Le espressioni regolari in quanto tali sono complesse ma anche molto potenti.

Quello che penso sia più confuso è che ogni libreria di supporto inventa la propria sintassi invece di usare (o estendere) la classica regex di Perl (es. \ 1, $ 1, {1}, ... per sostituzioni e molti altri esempi) .

So che sta rispondendo alla tua domanda nel modo sbagliato, ma RegExBuddy ha una funzione che spiega la tua regexpression in inglese semplice. Questo potrebbe rendere un po 'più semplice l'apprendimento.

Se la lingua che stai utilizzando supporta Posix regexes , puoi usarli.

Un esempio:

\d

sarebbe uguale a

[:digit:]

La notazione tra parentesi è molto più chiara su ciò che corrisponde. Imparerei ancora i caratteri e i simboli jolly & Quot; dal momento che li vedrai ancora nel codice di altre persone e dovrai capirli.

Ci sono altri esempi nella nella pagina regular-expressions.info .

Per qualche motivo, la mia risposta precedente è stata cancellata.Ad ogni modo, penso che la macchina Ruby regexp sia adatta al conto, a http://www.rubyregexp.sf.net.È un mio progetto, ma penso che dovrebbe funzionare.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top