Duct Tape a Regex Decider


11

Votre tâche consiste à créer un programme qui détermine si une chaîne donnée est une expression régulière valide ou non à l'aide d'extraits de code provenant de sites sur le réseau StackExchange.

Aux fins de ce défi, le dialecte d'expression régulière sera un ensemble dépouillé et la plupart du temps minimal de méta-caractères: ()*?|\. En tant que tel, vous ne pourrez pas utiliser les analyseurs regex intégrés.

  • \est utilisé pour échapper aux méta-caractères. Il doit être suivi d'un méta-caractère.
  • Les parenthèses non échappées doivent être équilibrées
  • *et ?doit être précédé d'un caractère non méta, d'un groupe entre parenthèses ou d'un méta caractère échappé.
  • Tous les autres caractères ASCII imprimables ainsi que la nouvelle ligne, la tabulation et l'espace doivent être pris en charge en tant que caractères non méta. Ce qui se passe avec une chaîne contenant d'autres caractères n'est pas défini.
  • La signification réelle de l'expression régulière n'est pas importante pour ce défi.

Exemples

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

Notation

Votre score global est le nombre d'extraits extraits des questions et réponses autour de StackExchange.

  • Les extraits de code répétés comptent autant de fois qu'ils sont utilisés.
  • Les espaces blancs peuvent être ajoutés et supprimés librement (en raison de Python, Haskell et d'autres langages sensibles aux espaces blancs) et ne comptent pas pour votre nombre d'extraits de code.
    • L'exception serait si votre code est réellement écrit en espace blanc .
  • Les extraits sont autorisés à partir de n'importe quel site StackExchange tant qu'ils proviennent de questions, réponses et commentaires qui sont plus anciens (y compris par le temps de modification - utilisez des révisions plus anciennes si nécessaire) que ce défi. (24 sept. 2019 à 15h30 UTC)
  • Les extraits de code peuvent provenir de n'importe où dans un corps de question, réponse ou commentaire, que ce soit dans un bloc de code préformaté ou non.
  • L'épissage d'un extrait au milieu d'un autre fait que l'extrait externe compte pour deux extraits

Le score le plus bas gagne!


1
@RobinRyder oui, changé
Beefster

La publication peut-elle être antérieure ou égale à ce défi, c'est-à-dire peut-on utiliser des extraits du corps de ce défi?
Jo King le

1
"En tant que tel, vous ne serez pas en mesure d'utiliser des analyseurs regex intégrés" Est-ce à dire que son conçu pour contrecarrer l'utilisation de cela pour un simple ya / nay, ou qu'il nous est interdit d'utiliser regex du tout dans nos réponses?
user0721090601

@guifa est conçu pour que vous ne puissiez pas simplement prendre le moteur d'expression régulière de votre langue et voir s'il compile l'expression régulière donnée. Chaque langue que je connais prend en charge un plus grand ensemble de métacaractères et de groupes de capture spécialisés, de sorte qu'ils ne correspondent pas correctement à cet ensemble de caractères dans tous les cas.
Beefster

1
@ JL2210 Cela en ferait deux extraits: un pour le début et un pour la fin. Vous pouvez utiliser un seul extrait tant qu'il réussit tous les cas de test et provient d'une réponse / question / publication antérieure à ce défi
Beefster

Réponses:


6

Perl 6 , 20 extraits

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

Essayez-le en ligne!

Les extraits sont extraits de:

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

Il s'agit principalement de l'approche gourmande (rendue évidente par tous les extraits d'un ou deux caractères). J'ai utilisé SymbolHound pour rechercher les caractères individuels, et la seule véritable optimisation était l' '(' <~~>* ')'extrait de code, qui est tiré de ma propre réponse sur les expressions rationnelles récursives de Perl 6.

Explication:

Cela vérifie essentiellement si l'entrée est égale à une correspondance gourmande d'une expression régulière valide. La raison pour laquelle nous ne pouvons pas simplement utiliser l'expression régulière elle-même et ajouter ^$pour marquer les fins est parce que nous utilisons une expression régulière récursive, qui ne fonctionnerait pas s'il y avait des ^$marqueurs. Le regex lui-même est:

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 ~~, merci!
user0721090601

@guifa Oui, j'ai appris cela grâce à la spécification P6 , qui contient beaucoup de choses qui n'ont pas encore été correctement documentées. Je soupçonne de ~~ne pas apparaître car il n'est pas encore complètement implémenté (par exemple <~~0>), bien qu'il y ait d'autres joyaux cachés là-dedans.
Jo King le
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.