Nastro adesivo un decisore Regex


11

Il tuo compito è quello di creare un programma che determina se una determinata stringa è un'espressione regolare valida o non utilizza frammenti di codice provenienti da siti sulla rete StackExchange.

Ai fini di questa sfida, l'espressione regolare dialettale sarà una serie ridotta e per lo più minimo di meta-caratteri: ()*?|\. Pertanto, non sarà possibile utilizzare i parser regex incorporati.

  • \è usato per sfuggire ai meta-personaggi. Deve essere seguito da un meta-personaggio.
  • Le parentesi senza escape devono essere bilanciate
  • *e ?deve essere preceduto da un non-meta-carattere, da un gruppo tra parentesi o da un meta-carattere sfuggito.
  • Tutti gli altri caratteri ASCII stampabili più newline, tab e spazio devono essere supportati come caratteri non meta. Ciò che accade con una stringa contenente altri caratteri non è definito.
  • Il significato reale della regex non è importante per questa sfida.

Esempi

Truthy:
  abc
  a?
  (a|)*
  ()
  a|b*
  \*
  \\
  \\*
  a*b?(cd|e)
  +
  [
  }
  (123\))*
  \|
  (a(b(c|d)*e)*f)*
  (|\)*)
  (abc)+*
  (abc)+
  +abc

^ last test case is an actual newline

Falsy:
  ?abc
  *
  **
  \
  (
  a*?
  a?*
  ?
  a)
  (\)
  (|\)*
  \()
  |*
  (?:abc)
  \\**
  \n

punteggio

Il tuo punteggio complessivo è il numero di frammenti tratti da domande e risposte su StackExchange.

  • Gli snippet ripetuti contano per tutte le volte che vengono utilizzati.
  • Gli spazi bianchi possono essere aggiunti e rimossi liberamente (a causa di Python, Haskell e altri linguaggi sensibili agli spazi bianchi) e non vengono conteggiati nel conteggio dei frammenti.
    • L'eccezione sarebbe se il tuo codice è effettivamente scritto in Whitespace .
  • Gli snippet sono consentiti da qualsiasi sito StackExchange purché provengano da domande, risposte e commenti più vecchi (incluso il tempo di modifica - se necessario, utilizzare revisioni precedenti) rispetto a questa sfida. (24 set 2019 @ 3:30 PM UTC)
  • Gli snippet possono provenire da qualsiasi parte del corpo di una domanda, risposta o commento, sia che si tratti di un blocco di codice preformattato o meno.
  • La giunzione di uno snippet nel mezzo di un altro fa sì che lo snippet esterno venga conteggiato come due snippet

Il punteggio più basso vince!


1
@RobinRyder sì, cambiato
Beefster

Il post può essere più vecchio o uguale a questa sfida, ovvero possiamo usare frammenti dal corpo di questa sfida?
Jo King,

1
"In quanto tale, non sarai in grado di utilizzare i parser regex incorporati". Vale a dire che è progettato per contrastare l'utilizzo per un semplice anno o no, o che ci è proibito usare regex nelle nostre risposte?
user0721090601

@guifa è progettato in modo da non poter semplicemente prendere il motore regex della tua lingua e vedere se compila la regex data. Ogni lingua che conosco supporta un set più ampio di meta-personaggi e gruppi di acquisizione specializzati, quindi non corrisponderebbero correttamente a questo set di caratteri in tutti i casi.
Beefster,

1
@ JL2210 Ciò renderebbe due frammenti: uno per l'inizio e uno per la fine. Puoi utilizzare un singolo frammento purché superi tutti i casi di test e provenga da una risposta / domanda / post più vecchia di questa sfida
Beefster,

Risposte:


6

Perl 6 , 20 frammenti

{$_ eq m/[[<-[()*?|\\]>|\\<[()*?|\\]>|'(' <~~>* ')']<[*?]>?|\|]+/}

Provalo online!

I frammenti sono presi da:

{$_ eq, m/[, <-[, ()*?, |\\, ]>, |\\, <[, ()*?, |\\, ]>, |, '(' <~~>* ')', <[, *?, ]>, ?|, \|, ]+/, }.

Questo è principalmente l'approccio avido (reso evidente da tutti i frammenti di uno o due personaggi). Ho usato SymbolHound per cercare i singoli personaggi e l'unica vera ottimizzazione era lo '(' <~~>* ')'snippet, che è tratto dalla mia risposta sulle regex ricorsive di Perl 6.

Spiegazione:

Questo in pratica controlla se l'input è uguale a una corrispondenza avida di una regex valida. Il motivo per cui non possiamo semplicemente usare la regex stessa e aggiungere ^$per segnare le estremità è perché stiamo usando una regex ricorsiva, che non funzionerebbe se ci fossero ^$marcatori. La regex stessa è:

m/[                             ]+/   # Match one or more times
   [              ]  # Any of 
    <-[()*?|\\]> |     # Not a metacharacter
    \\<[()*?|\\]>      # A metacharacter preceded by a \
    '(' <~~>* ')'      # Brackets surrounding a valid regex
                   <[*?]>?  # Optionally followed by a ? or *
                           | \|    # Or just the | metacharacter

TIL ~~, grazie!
user0721090601

@guifa Sì, l'ho imparato attraverso la specifica P6 , che contiene molte cose che non sono ancora state adeguatamente documentate. Sospetto ~~che non appaia perché non è ancora completamente implementato (ad esempio <~~0>), anche se ci sono altre gemme nascoste.
Jo King,
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.