0
votes

REGEX correspondant aux caractères d'espacement et plusieurs modèles facultatifs avant le début du texte

Je suis d'analyse des chaînes contenant du code comme ce qui suit. Il peut commencer par une ligne vide suivie de plusieurs modèles facultatifs. Ces modèles peuvent soit des commentaires en ligne de style Python (en utilisant un caractère de hachage), soit la commande "! MyCommand", et les deux doivent commencer au début d'une ligne. Comment puis-je écrire une correspondance de regex jusqu'au démarrage du code? XXX

Je souhaite que le regex correspond à la chaîne jusqu'à "du code. Catch jusqu'à la ligne précédente". J'ai essayé différentes choses mais je suis probablement coincé avec les deux modèles multiples


0 commentaires

3 Réponses :


1
votes

Votre modèle correspond une instance de # ... ou ! myCommand . Un moyen de résoudre ce problème est de les mettre d'entre eux dans une correspondance et d'utiliser re.search pour trouver le premier match.

Pour ce faire, vous devez répéter la partie qui correspond à < code> # ... ou ! myCommand Utilisation * : xxx

J'ai aussi changé < Code> #. * à #. * \ s * de sorte qu'il va jusqu'à la ligne suivante où une utilisation non blanche est trouvée.

< Un href = "https://regex101.com/r/kxr22a/1" rel = "Nofollow NOREFERRER"> Demo

Répondre à votre commentaire:

Si la chaîne commence par code, cette regex ne doit pas correspondre à rien

Vous pouvez essayer: xxx

j'ai changé en \ a de sorte qu'il ne correspond que le début absolu de la chaîne, au lieu de début de ligne. J'ai aussi changé le dernier * sur + au moins un # ... ou ! MyCommand doit être présent.


7 commentaires

Deux petits problèmes: 1) Si la chaîne commence par le code, cette regex ne doit pas correspondre à rien; 2) le personnage de la nouvelle ligne avant que le code ne soit inclus dans le match


Lorsque vous dites "commence par le code", est la ligne vide au début là-bas? Le personnage de la nouvelle ligne avant le code est inclus dans le match. @ aless80


Oui, vous avez raison sur le point 1 et c'est ce dont j'ai besoin. Maintenant, laissez-moi réparer le point deux. ajouter A \ s * n'aide pas


@ aless80 Voir la modification. Ai-je bien compris correctement? Si j'ai mal compris et que la réponse à mon commentaire précédent était en réalité «non», changez le premier * à + , plutôt que le dernier < Code> * .


La modification sur le début absolu \ A est une bonne, mais je ne veux pas le dernier +. À ce stade, ce qui manque, c'est d'attraper des caractères nouveaux / espaces juste avant la ligne de code, qui dans mon exemple est "du code. Correspondre jusqu'à la ligne précédente"


@ aless80 correspond à de nouvelles lignes juste avant le code . Voir le symbole "Entrée" après "Bonjour"? Ou parlez-vous de quelque chose d'autre?


Laissez-nous Continuez cette discussion en chat .



2
votes

correspondant et renvoyant les commentaires au début de la chaîne forte>

Pas besoin d'une regex, de lecture et d'apportez les lignes à la liste jusqu'à une ligne qui ne commence pas avec ! ou # code> se produit et ignore toutes les lignes vides: p> xxx pré>

voir le Python démo . Résultats: P> xxx pré>

Supprimer les commentaires au début de la chaîne forte> p> xxx pré>

sortie: p>

print(re.sub(r'^(?:[^\S\n]*(?:[!#].*)?\n)+', '', mystring, count=1))


6 commentaires

En effet, c'est probablement une bonne idée d'éviter les regex. Laisse moi y réfléchir


Je n'ai pas écrit que dans ma question, mais mon objectif final est en fait avoir la partie de code de ma chaîne. En d'autres termes, je veux supprimer les nouvelles lignes initiales, les commentaires et! MyCommand. J'ai édité votre code de sorte que le résultat ressemble à la mystring (avec \ n ou espaces), puis je "substrait" résultat de mystring. Cependant, je ne suis pas sûr à quel point cette méthode sera robuste


@ aless80 Vous voulez donc dire que vous devez supprimer tous les du code. correspondre jusqu'à la ligne précédente ?


@ aless80 Vous pouvez toujours l'obtenir sans regex, mais c'est à vous de choisir le chemin.


L'inconvénient de votre 2e approche est que la boucle pour passer à travers toutes les lignes. Dans mon approche, je reçois la correspondance d'une manière similaire à votre première approche, alors mystring [len (résultat):]. Cependant, je pense que je choisis pour l'approche de regex (espérons-le plus "fiable")


@ Aless80 a ajouté une approche de regex. Je vous suggère d'utiliser comptez = 1 sur re.sub le texte correspondant une fois . Notez que \ a ancreur ne signifie pas re.sub arrêtera de vérifier le reste des lignes, cela continuera. \ a signifie qu'il n'y aura pas de correspondance. Count = 1 garantit qu'il s'arrête même à la recherche des matchs après la première partie de la première.



2
votes

Sans la nécessité de ré.multiline em> Vous pouvez correspondre à plusieurs fois 0+ caractères blancheurs avant et après la correspondance

import re
m = re.search(r'^(?:\s*(?:#.*|!mycommand\s*))+\s*', mystring)
print(m.group())


0 commentaires