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? 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 p> p>
3 Réponses :
Votre modèle correspond une instance em> de Pour ce faire, vous devez répéter la partie qui correspond à < code> # ... code> ou J'ai aussi changé < Code> #. * code> à < Un href = "https://regex101.com/r/kxr22a/1" rel = "Nofollow NOREFERRER"> Demo P> Répondre à votre commentaire: P> Si la chaîne commence par code, cette regex ne doit pas correspondre à rien p>
blockquote> Vous pouvez essayer: p> j'ai changé en # ... code> ou ! myCommand code>. Un moyen de résoudre ce problème est de les mettre d'entre eux dans une correspondance et d'utiliser re.search code> pour trouver le premier match. ! myCommand code> Utilisation * code>: p> #. * \ s * code> de sorte qu'il va jusqu'à la ligne suivante où une utilisation non blanche est trouvée. p>
\ a code> 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 * code> sur + code> au moins un # ... code> ou ! MyCommand code> doit être présent. p> p>
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 i> 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 i> * code> à + code>, plutôt que le dernier < Code> * 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 .
Pas besoin d'une regex, de lecture et d'apportez les lignes à la liste jusqu'à une ligne qui ne commence pas avec voir le Python démo . Résultats: P> Supprimer les commentaires au début de la chaîne forte> p> sortie: p> ! ou # code> se produit et ignore toutes les lignes vides: p> print(re.sub(r'^(?:[^\S\n]*(?:[!#].*)?\n)+', '', mystring, count=1))
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 code>?
@ 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 code> sur re.sub code> le texte correspondant une fois i>. Notez que \ a code> ancreur ne signifie pas re.sub code> arrêtera de vérifier le reste des lignes, cela continuera. \ a code> signifie qu'il n'y aura pas de correspondance. Count = 1 Code> garantit qu'il s'arrête même à la recherche des matchs après la première partie de la première.
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())