J'essaie d'utiliser une expression régulière pour faire correspondre les entrées entre les barres obliques dans le texte ci-dessous:
311102Z/5663.00N/00813.02E/GPS//03/-/
Pour cet exemple, les résultats devraient être une série de correspondances qui ont le contenu:
311102Z 5663.00N 00813.02E GPS 03 - Il est important d'attraper l'entrée vide et de renvoyer une correspondance vide. Malheureusement, pour diverses raisons, nous ne pouvons pas utiliser le regroupement ici, ni faire correspondre les barres obliques elles-mêmes et les diviser.
J'ai le regex suivant comme quelque chose qui fonctionne presque: (. *? ) (? = /) . Un affichage interactif de cette expression régulière peut être vu ici . Il correspond bien à toutes les entrées, mais a des correspondances vides supplémentaires à la fin de chaque entrée.
J'ai essayé de remplacer le * par un + , mais bien sûr, cela signifiait qu'il ne correspondait pas à l'entrée vide.
Quelqu'un a-t-il des idées sur ce que je pourrais faire pour que cela corresponde à ce que je veux - c'est-à-dire. sans ces correspondances vides supplémentaires, mais avec l'entrée vide à la position où il n'y a pas de caractères entre les barres obliques.
Si c'est important pour la compatibilité, J'utilise cette regex en Python.
5 Réponses :
Vous pouvez utiliser cette expression régulière avec des assertions lookahead et lookbehind:
>>> import re >>> s = '311002Z/3623.00N/00412.02E/GPS//03/-/' >>> print (re.findall(r'(?:(?<=/)|^)[^/]*(?=/)', s)) ['311002Z', '3623.00N', '00412.02E', 'GPS', '', '03', '-']
(?:(?<=/)|^)[^/]*(?=/)
Détails RegEx: p>
(?: (? : Regardez derrière pour affirmer que nous avons soit start, soit / à la position précédente [^ /] * : correspond à 0 ou plus de tout caractère qui n'est pas / (? = /) : Lookahead pour affirmer que nous avons un / devant Vous pouvez utiliser re.split pour cela (comme str.split , en utilisant uniquement une expression régulière), puis en supprimant le dernier élément:
>>> import re
>>> foo = "311102Z/5663.00N/00813.02E/GPS//03/-/"
>>> re.split("/", foo)[:1]
['311102Z', '5663.00N', '00813.02E', 'GPS', '', '03', '-']
C'était ma première suggestion à OP dans les commentaires mais malheureusement OP ne peut pas utiliser de groupes de capture.
Ensuite, je suggérerais:
['311102Z', '5663.00N', '00813.02E', 'GPS', '', '03', '-']
qui renvoie
import re
entry = "311102Z/5663.00N/00813.02E/GPS//03/-/"
match = re.findall("([^/]*)/", entry)
print(match)
C'était ma première suggestion à OP dans les commentaires mais malheureusement OP ne peut pas utiliser de groupes de capture.
On dirait qu'OP a une base de code problématique alors :)
Comme alternative, vous pouvez faire correspondre plus de 1 fois n'importe quel caractère sauf / , en affirmant un / sur la droite.
Ou obtenir la position entre 2 barres obliques .
'311102Z', '5663.00N', '00813.02E', 'GPS', '', '03', '-']
Explication
[^ /] + (? = /) Correspond à plus de 1 fois n'importe quel caractère sauf / et affirmez un / à droite
| Ou (? Obtenir la position entre 2 barres obliques Exemple de code
import re s="311102Z/5663.00N/00813.02E/GPS//03/-/" pattern = r"[^/]+(?=/)|(?<=/)(?=/)" print(re.findall(pattern, s))
Sortie
[^/]+(?=/)|(?<=/)(?=/)
Encore un (Python):
(?<=/) : use a positive lookbehind to assert match is preceded by '/' (?=/) : use a positive lookahead to assert match is followed by '/' | : or [^/]+ : match 1+ characters other than '/'
(?<=/)(?=/)|[^/]+
Remplacez [^ /] + par [^ / \ n] + pour empêcher correspond à des terminateurs de ligne couvrant.
Bonjour, j'ai publié une question aujourd'hui stackoverflow.com/questions/62607380/... , Si vous connaissez une nouvelle façon de résoudre le problème, pouvez-vous y poster?
Pourquoi avez-vous besoin d'utiliser une regex? On dirait que vous pourriez simplement utiliser
str.split ("/")?Vous pouvez simplement utiliser
([^ /] *) /comme expression régulière voir la démo: regex101.com/r/AGMfuk/2@PeterH. Malheureusement pour la compatibilité avec le reste du système, nous devons utiliser une regex pour cela - comme toutes les autres lignes que ce code doit traiter nécessitent une regex pour se diviser.
@anubhava Merci, mais malheureusement, nous devons avoir la correspondance complète sans la barre oblique à la fin, encore une fois en raison d'autres exigences du système, nous ne pouvons pas simplement sélectionner le premier groupe. Par «correspondance complète», j'entends ici que chacune des correspondances de ma liste à puces doit être le contenu complet du match, et non le contenu d'un groupe dans le match.
lst = s [: - 1] .split ('/')aiderait-il? Oùsest votre chaîne?Cette question ressemble à un problème xy
@Ruzihm, je ne vois pas pourquoi. Le PO a clairement énoncé le problème sans faire référence à une approche à adopter.
@CarySwoveland utilisant une expression régulière est l'approche supposée pour une vague «compatibilité».