J'ai un ensemble d'entrées. J'essaie d'écrire une expression régulière pour correspondre au modèle suivant dans l'entrée:

Jour à Heure sur emplacement

Exemple d'entrée:

Aujourd'hui à 12h30 dans le salon de Sam

La partie en gras du texte varie dans chaque entrée.

J'ai écrit l'expression régulière suivante:

import regex as re

input_example = "Today at 12:30 PM on Rakesh's Echo"
regexp_1 = re.compile(r'(\w+) at (\d+):(\d+) (\w+) on (\w+)')
re_match = regexp_1.match(input_example)

Ce qui fonctionne, je fais correspondre les bons modèles. J'essaie maintenant d'extraire des groupes de l'intérieur du modèle.

Ma sortie souhaitée est:

re_match.group(1)
>> "Today"
re_match.group(2)
>> "12:30 PM"
re_match.group(3)
>> "Sam's living room"

Cependant, ma correspondance d'expression régulière actuelle ne me donne pas cette sortie. Quel est le regex correct qui me donnera les sorties ci-dessus?

1
Rakesh Adhikesavan 16 avril 2018 à 18:49

4 réponses

Meilleure réponse

Tu es assez proche. Vous voulez juste ajuster un peu vos groupes de capture pour ressembler à ...

re.compile(r"(\w+) at (\d+:\d+ \w+) on (.+)")

Notez que le deuxième groupe de capture correspondra désormais au hour:minute period-of-day complet. Le groupe de capture final (\w+) correspondra à a-z, A-Z, 0-9 et _, mais pas ', mais pas ', ce qui vous obligera à capturer uniquement un petit morceau de la description. Le passage à .+ lui permet de correspondre à n'importe quel caractère. Si vous savez que seuls quelques caractères en dehors de \w doivent être mis en correspondance, vous pouvez faire [\w']+ avec les autres caractères dont vous avez besoin inclus.

Un bon outil pour jouer avec et tester votre regex est https://regex101.com/ assurez-vous simplement de sélectionner langage python.

3
rsiemens 16 avril 2018 à 15:59

Je pense que vous préférez re.compile(r'(\w+) at (\d+:\d+ \w+) on (.+)').

Votre deuxième groupe doit capturer tout le temps (deux chiffres et un mot) et votre troisième groupe doit accepter plus que \w si vous voulez obtenir des apostrophes, etc. Je suggère .+ qui obtiendra juste tout à la fin de la ligne.

J'ai essayé cela et j'ai:

Aujourd'hui

12 h 30

Écho de Rakesh

1
moopet 14 août 2019 à 08:12

Tout ce que vous avez entre parenthèses () sera un groupe de capture.

Essayez ceci: (\w*) at (\d+:\d+ \w+) on (.*).

Donc alors,

1st group --> \w*

2nd group --> \d+:\d+ \w+

3rd group --> .*

Ce qui vous donne:

1st group --> Today

2nd group --> 12:30 PM

3rd group --> Rakesh's Echo
1
Colin Ricardo 16 avril 2018 à 15:59

Vous pouvez créer des groupes imbriqués, mais de cette façon, ce ne serait pas très lisible, car vous devez calculer le nombre exact du groupe, puis vous oublierez ce que signifie exactement ce nombre.

Il est préférable d'utiliser des groupes nommés. Ceci est copié à partir du REPL:

>>> import re
... 
... input_example = "Today at 12:30 PM on Rakesh's Echo"
... regexp_1 = re.compile(r'(?P<day>\w+) at (?P<time>(\d+):(\d+) (\w+)) on (?P<place>\w+)')
... re_match = regexp_1.match(input_example)
>>> list(re_match.groups())
['Today', '12:30 PM', '12', '30', 'PM', 'Rakesh']
>>> re_match.group('day')
'Today'
>>> re_match.group('time')
'12:30 PM'
>>> re_match.group('place')
'Rakesh'
1
Mariy 16 avril 2018 à 15:58