J'ai un peu de mal à faire fonctionner une expression régulière Python lors de la correspondance avec du texte qui s'étend sur plusieurs lignes. L'exemple de texte est ('\ n' est une nouvelle ligne)
some Varying TEXT\n
\n
DSJFKDAFJKDAFJDSAKFJADSFLKDLAFKDSAF\n
[more of the above, ending with a newline]\n
[yep, there is a variable number of lines here]\n
\n
(repeat the above a few hundred times).
Je voudrais capturer deux choses: la partie 'some_Varying_TEXT' et toutes les lignes de texte majuscules qui viennent deux lignes en dessous dans une capture (je peux supprimer les caractères de nouvelle ligne plus tard). J'ai essayé avec quelques approches:
re.compile(r"^>(\w+)$$([.$]+)^$", re.MULTILINE) # try to capture both parts
re.compile(r"(^[^>][\w\s]+)$", re.MULTILINE|re.DOTALL) # just textlines
et de nombreuses variantes sans chance. Le dernier semble correspondre aux lignes de texte une par une, ce qui n'est pas ce que je veux vraiment. Je peux attraper la première partie, pas de problème, mais je n'arrive pas à attraper les 4-5 lignes de texte en majuscules. Je voudrais que match.group (1) soit some_Varying_Text et group (2) soit line1 + line2 + line3 + etc jusqu'à ce que la ligne vide soit rencontrée.
Si quelqu'un est curieux, c'est censé être une séquence d'acides aminés qui composent une protéine.
>
caractère principal . Devrait-il?Réponses:
Essaye ça:
Je pense que votre plus gros problème est que vous vous attendez à ce que les ancres
^
et$
correspondent aux sauts de ligne, mais ce n'est pas le cas. En mode multiligne,^
correspond à la position immédiatement après une nouvelle ligne et$
correspond à la position précédant immédiatement une nouvelle ligne.Sachez également qu'une nouvelle ligne peut être constituée d'un saut de ligne (\ n), d'un retour chariot (\ r) ou d'un retour chariot + saut de ligne (\ r \ n). Si vous n'êtes pas certain que votre texte cible n'utilise que des sauts de ligne, vous devez utiliser cette version plus inclusive de l'expression régulière:
BTW, vous ne voulez pas utiliser le modificateur DOTALL ici; vous vous fiez au fait que le point correspond à tout sauf aux retours à la ligne.
la source
Cela fonctionnera:
Quelques explications sur cette expression régulière peuvent être utiles:
^(.+?)\n\n((?:[A-Z]+\n)+)
^
) signifie "commençant au début d'une ligne". Sachez qu'il ne correspond pas à la nouvelle ligne elle-même (même chose pour $: cela signifie "juste avant une nouvelle ligne", mais cela ne correspond pas à la nouvelle ligne elle-même).(.+?)\n\n
signifie "correspondre le moins de caractères possible (tous les caractères sont autorisés) jusqu'à ce que vous atteigniez deux nouvelles lignes". Le résultat (sans les nouvelles lignes) est placé dans le premier groupe.[A-Z]+\n
signifie "correspond à autant de lettres majuscules que possible jusqu'à ce que vous atteigniez une nouvelle ligne. Ceci définit ce que j'appellerai une ligne de texte .((?:
textline)+)
signifie correspondre à une ou plusieurs lignes de texte mais ne pas mettre chaque ligne dans un groupe. Au lieu de cela, mettez toutes les lignes de texte dans un groupe.\n
dans l'expression régulière si vous souhaitez appliquer un double saut de ligne à la fin.\n
ou\r
ou\r\n
), corrigez simplement l'expression régulière en remplaçant chaque occurrence de\n
par(?:\n|\r\n?)
.la source
Si chaque fichier ne contient qu'une seule séquence d'acides aminés, je n'utiliserais pas du tout d'expressions régulières. Juste quelque chose comme ça:
la source
trouver:
\ 1 = some_varying_text
\ 2 = lignes de tous les CAPS
Edit (preuve que cela fonctionne):
la source
Voici une expression régulière correspondant à un bloc de texte multiligne:
la source
Ma préférence.
À ce stade, vous avez someVaryingText sous forme de chaîne et les acides sous forme de liste de chaînes. Vous pouvez
"".join( acids )
faire une seule chaîne.Je trouve cela moins frustrant (et plus flexible) que les expressions rationnelles multilignes.
la source