Je regarde autour de moi et je ne pouvais pas y arriver. Je ne suis pas totalement noob. P>
J'ai besoin d'obtenir du texte délimité par (y compris) début et fin qui ne contient pas de début. Fondamentalement, je ne trouve pas un moyen de nier un mot entier sans utiliser de choses avancées. P>
Exemple de chaîne: p>
abcstartabcstartabcendabc p> blockQuote>
Le résultat attendu: p>
startabcend p> blockQuote>
pas bon: p>
startabcstartabcend p> blockQuote>
Je ne peux pas utiliser de choses de recherche en arrière. Je teste ma regex ici: www.regexter.com p>
Merci pour tout conseil. P>
5 Réponses :
Essayez ceci voir ici en ligne sur Regexr P > mise à jour: p> Je pensais un peu plus, la solution ci-dessus correspond à la première "FINIR". Si cela n'est pas recherché (parce que vous excluez le début du contenu), utilisez la version gourmande p> Ceci correspondra à la dernière "fin". P> < / p> (?!. * Démarrer) code> est un regard négatif. Il garantit que le mot "démarrage" ne suit pas p>
. *? Code> est une correspondance non gourmande de tous les caractères jusqu'à la prochaine "fin". C'est nécessaire, parce que la lunette de regard négatif est juste à l'avenir et ne capturant rien (affirmation de longueur zéro) p>
+1 pour une bonne réponse avec des explications simples de tous les opérateurs
Cela échouera s'il y a plus d'un Démarrer ... fin code> paire dans la chaîne. (Ou plus précisément, il ne trouvera que le dernier
Démarrer ... fin code> paire dans la chaîne.)
Pour clarifier le commentaire de Tim: votre regexp ne correspondra pas là où vous vous attendez à ce qu'il y a si il y a n'importe quel article i> deuxième occurrence de Démarrer code>, que ce soit avant i> ou < I> après i>
fin code> (par exemple,
abcstartabcendxyzstart code> ne correspondra pas)
Oui, cela demande simplement s'il y a une occurrence de départ à l'avenir et, dans l'affirmative, ne correspondra pas. Ce n'est pas le comportement recherché (décrit).
La solution vraiment piétonne serait départ (([^ s] | s * s [^ st] | st [^ a] | sta [^ r] | star [^ t]) * (S ( T (ar?)?)?) Finalement code>. Les saveurs de regex modernes ont des assertions négatives qui le font plus élégamment, mais j'interprète votre commentaire sur la "recherche à l'envers" pour signifier peut-être que vous ne pouvez ni utiliser cette fonctionnalité. P>
start ((([^ es] | e * e [^ ens] | EN [^ DS] | S * s [^ Ste ] | St [^ ae] | STA [^ re] | Star [^ te]) * (S (t (T (ar?)?)? | Fr?)?) Fin code>. Cela risque de dépasser le seuil de torture dans la plupart des cultures, cependant. P>
Sstart code> pourrait faire partie de la correspondance (le second
s code> correspondrait à
[^ t] code>, etc.). J'ai réparé cela mais par l'ajout de
s code> dans
[^ st] code> et ajout
s * code> avant le non-optionnel
s Code> Pour permettre des répétitions arbitraires de
S code> sinon. p>
Belle solution (si pas de lunettes de lookaheads) +1
C'est ce que je cherchais, merci. En effet ... piéton :) mais ça marche. J'espérais qu'il pourrait y avoir une façon plus facile que je manque. Désolé de ne pas poster plus tôt.
Quelle est la dernière partie? Pourquoi avez-vous besoin (s (t (ar?)?)?)? Code>
D'accord! Je l'obtiens ... Vous avez besoin de ... (s (t (t (ar?)?)?)? ... code> Parce que, autrement, vous devez consommer des caractères après
s code >,
st code>,
STA code> et
étoile code> ... Ceci est Freaking Genius.
Je ne sais pas ce que tu veux dire par ça. Une sous-chaîne de démarrage est autorisée avant le délimiteur de fin et de la manière dont nous avons empêché ces sous-chaînes de correspondance.
Je ne comprends pas la réponse. Ma question était pourquoi avez-vous besoin d'avoir cette partie (s (t (t (ar (ar?)?)?)?)? Code> Mais je pense que la raison en est que vous ne correspondez pas à quelque chose comme
StartStarend code>. Le
(s (t (t (ar (ar?)?)?)? Code> Consommez-vous de manière proprement toute sous-chaîne de
étoile code> qui vient directement avant
extrémité code>.
Oui, exactement. Plus tôt dans le match, nous autorisons star code> s'il est suivi de quelque chose i> qui n'est pas
t code>, mais juste avant le délimiteur de fin, nous autorisons également Il doit être suivi de rien i>. (Utiliser "Consommer" dans ce contexte est un peu bizarre, IMHO, cependant.)
Merci de me pousser, je pense avoir trouvé un bug, bien que ce ne soit pas directement lié à cela. Je vais essayer de le réparer demain.
[EDIT: J'ai quitté cet article pour les informations sur les groupes de capture, mais la solution principale que j'ai donnée n'était pas correcte.
La réponse donnée à l'aide de l'opérateur "zéro-largeur négatif" "?!", avec des groupes de capture, c'est: De cette façon si vous l'utilisez pour effectuer la recherche et le remplacer, vous pouvez le faire, quelque chose comme Begn $ 1inish. Donc, si vous avez commencé avec: p>
Vous obtiendrez Qui vous permettrait de modifier vos jetons de démarrage / extrémité uniquement lorsqu'il est associé correctement. p>
chaque Voir le Documentation Java Regex < / a> Pour plus de détails sur Java Regexes. P> (? Démarrer) ((?: [^ S] | S [^ T] | ST [^ R] | STAR [^ T]) *) (?? ) code> grève>
Comme indiqué dans les commentaires ne fonctionnerait pas; J'oubliais que les personnages ignorés ne pouvaient pas être abandonnés et que vous auriez donc besoin de quelque chose comme ...
| sta (?! [^ r]) | code> Pour toujours permettre à ce personnage de faire partie de la fin. , partant, échouant à quelque chose comme StartStaend; Donc, c'est clairement un meilleur choix; Les éléments suivants doivent indiquer la bonne façon d'utiliser les groupes de capture ...] p>
(? Démarrer) ((?! * Démarrer). *) (? ) code> qui capture le texte interne en utilisant 1 $ pour le remplacement. Si vous souhaitez avoir les balises de démarrage et de fin capturées, vous pourriez faire
(départ) ((? *. * Démarrer). *) (Fin) code> qui donne $ 2 = Texte ou diverses autres permutations en ajoutant / supprimer
() code> s ou
?: code> s. P>
abcstartdefstarghiendjkl code> p>
ghi code> comme groupe de capture 1 et remplaçant par Begin $ 1Finish vous donnerait les suivants: p>
abcstartdefbeginghifinishjkl code> p>
(x) code> est un groupe, mais j'ai mis
(?: x) code> pour chacun des celles sauf le milieu qui la marque comme une non-capture grouper; le seul que j'ai laissé sans un
?: code> était le milieu; Cependant, vous pouvez également saisir éventuellement les jetons de début / fin si vous vouliez les déplacer ou quoi-vous-êtes. P>
Vous échouez sur le modèle STRATTAEND.
@tripleee soupir, oui, en effet et je devrais ignorer ces personnages avec ?! ce qui défait un peu le but. Je vous remercie de le faire remarquer.
>>> re.findall(r"(?<=START)(?:(?!START).)*(?=END)", a) ['def', 'jlk', 'uvw']
Yup, cela le fera. +1 (Bien que vous puissiez vouloir mentionner / utiliser le drapeau s code> dot-correspondant.)
Puis-je suggérer une éventuelle amélioration de la solution de Tim Pietzcker?
Il me semble que commencer (? :( ?! Démarrer).).) *? Fin code> est meilleur pour attraper un
Démarrer code> immédiatement suivi d'un extrémité
code> sans aucun
Démarrer code> ou
fin code> entre les deux. J'utilise la solution .NET et TIM correspondent également à quelque chose comme
Démarrer la fin de fin code>. Au moins dans mon cas personnel, cela n'est pas recherché. P>
Et si le texte est
abcstartabcendabcstartabcendabc code>? Voulez-vous les deux matchs?
N'ai-je pas pensé à ça ... Quoi qu'il en soit, je peux trouver deuxième match si nécessaire.
Mieux vaut faire cela dans une seule regex. J'ai ajouté une réponse.
Vous pouvez tester votre regex à Rubular.com