2
votes

Un mot commençant par t mais se terminant par un autre que e

J'essaie de créer une expression régulière qui commence par t ou T et ne se termine pas par une lettre e. J'ai essayé le code ci-dessous jusqu'à présent, mais cela ne me donne pas le résultat souhaitable. Quelqu'un pourrait-il me montrer ce qui manque exactement ici?

my_str = my_file.read()

word = re.findall("[tT].*[^e]$", my_str)

print(word)


6 commentaires

Essayez-vous de trouver des mots dans une phrase / texte complet? Ou est-ce une base de données avec un seul mot par ligne? En d'autres termes, avez-vous des exemples de données? Btw, actuellement vous autorisez n'importe quel caractère autre que le saut de ligne entre les deux (y compris les caractères d'espace).


Oui, c'est un texte dans le fichier.


Vous voudrez peut-être savoir que \b dans une expression régulière correspond à une limite de mot…


Ensuite, vous devez décider de ce qu'est un caractère juridique à l'intérieur d'un mot. [A-Za-z] est probablement une meilleure estimation que la vôtre . (c'est-à-dire tout ce qui comprend la ponctuation et les espaces).


Enfin, si vous avez résolu votre problème, vous pouvez publier une réponse que je serai ravie de voter.


Dans ce texte "Ici nous désignons le temps avec la variable t, la distance avec x." le mot «t» répond-il à vos critères?


3 Réponses :


3
votes

Vous pouvez utiliser

import re
text = r't, train => main,teene!'
cyr_text = r'таня  тане  работе'
print( re.findall(r'\bt(?:[a-z]*[a-df-z])?\b', text, re.I) )
# => ['t', 'train']
print( re.findall(r'\bt[a-z]*\b(?<!e)', text, re.I) )
# => ['t', 'train']
print( re.findall(r'\bт[^\W\d_]*\b(?<!е)', cyr_text, re.I) )
# => ['таня']
print( re.findall(r'(?<![^\W\d_])т[^\W\d_]*(?![^\W\d_])(?<!е)', cyr_text, re.I) )
# => ['таня']

Juste pour être complet, voici une regex pour faire correspondre n'importe quel mot commençant par un cyrillique Ñ‚ et ne se terminant pas par un cyrillique е :

r'(?<![a-z])t(?:[a-z]*[a-df-z])?(?![a-z])'
r'(?<![^\W\d_])т[^\W\d_]*(?![^\W\d_])(?<!е)' # Unicode letter boundaries

Voir la démo regex n ° 1 , la démo regex n ° 2 et une démo regex cyrillique .

Si vous avez besoin d'une correspondance insensible à la casse, ajoutez re.I :

re.findall(r'\bt(?:[a-z]*[a-df-z])?\b', text, re.I)

Et une note sur les limites des mots: si les mots peuvent être collés à _ ou à des chiffres, utilisez des limites de lettre plutôt que des limites de mot:

\bт[^\W\d_]*\b(?<!е)

Détails Regex

  • \b - limite de mot (début de chaîne ou position immédiatement après un caractère autre qu'un chiffre, une lettre, un trait de soulignement)
  • (?<![az]) ( (?<![^\W\d_]) est un équivalent compatible Unicode) - un regard négatif qui correspond à un emplacement qui n'est pas immédiatement précédé d'une lettre
  • t - une lettre t
  • (?:[az]*[a-df-z])? - un groupe optionnel non capturant correspondant à 0 lettres ou plus, puis à une lettre autre que e
  • \b - limite de mot
  • (?![az]) ( (?![^\W\d_]) est un équivalent compatible Unicode) - une anticipation négative qui correspond à un emplacement qui n'est pas immédiatement suivi d'une lettre.

Aussi,

  • \bt[az]*\b(?<!e) correspond à une limite de mot, t , zéro ou plusieurs lettres ASCII minuscules (toutes les lettres ASCII avec re.I ), puis une limite de mot marque la fin d'un mot et le lookbehind négatif (?<!e) échoue la correspondance s'il y a e à la fin du mot
  • [^\W\d_]* - correspond à zéro ou plusieurs lettres Unicode.

Voir une démo Python :

\bt(?:[a-z]*[a-df-z])?\b
\bt[a-z]*\b(?<!e)


0 commentaires

0
votes

Peut être:

[\W]([Tt]\w*[^e])[\W]

Tout caractère autre qu'un mot suivi de (capture: Tt, certains caractères facultatifs de mot, pas e) suivi du premier caractère autre qu'un mot


0 commentaires

0
votes

Il existe également une autre façon de procéder:

re.findall(r"\b[Tt]+[a-zA-Z]*[^Ee\s]\b", my_str)


0 commentaires