web-dev-qa-db-fra.com

Utiliser ^ pour faire correspondre le début de ligne dans une expression rationnelle Python

J'essaie d'extraire des données de type ISI d'années de publication du Web of Science de Thomson-Reuters. La ligne pour "Année de publication" ressemble à ceci (au tout début d'une ligne): 

PY 2015

Pour le script que j'écris, j'ai défini la fonction regex suivante:

import re
f = open('savedrecs.txt')
wosrecords = f.read()

def findyears():
    result = re.findall(r'PY (\d\d\d\d)', wosrecords)
    print result

findyears()

Ceci, cependant, donne des résultats faussement positifs car le motif peut apparaître ailleurs dans les données. 

Donc, je veux seulement faire correspondre le motif en début de ligne. Normalement, j'utiliserais ^ à cette fin, mais r'^PY (\d\d\d\d)' ne parviendrait pas à faire correspondre mes résultats. D'un autre côté, utiliser \n semble faire ce que je veux, mais cela pourrait entraîner d'autres complications pour moi.

13
chrisk
re.findall(r'^PY (\d\d\d\d)', wosrecords, flags=re.MULTILINE)

devrait fonctionner, laissez-moi savoir si cela ne fonctionne pas. Je n'ai pas vos données.

12
sinhayash

Utilisez re.search avec re.M:

import re
p = re.compile(r'^PY\s+(\d{4})', re.M)
test_str = "PY123\nPY 2015\nPY 2017"
print(re.findall(p, test_str)) 

Voir Démo IDEONE

EXPLICATION:

  • ^ - Début de ligne (en raison de re.M)
  • PY - Littéral PY
  • \s+ - 1 ou plusieurs espaces
  • (\d{4}) - Groupe de capture contenant 4 chiffres
3
Wiktor Stribiżew

Dans ce cas particulier, il n'est pas nécessaire d'utiliser des expressions régulières, car la chaîne recherchée est toujours 'PY' et doit figurer au début de la ligne. Vous pouvez donc utiliser string.find pour ce travail. La fonction find renvoie la position dans laquelle la sous-chaîne est trouvée dans la chaîne ou la ligne donnée. Ainsi, si elle se trouve au début de la chaîne, la valeur renvoyée est 0 (-1 si elle ne se trouve pas du tout), c'est-à-dire:

In [12]: 'PY 2015'.find('PY')
Out[12]: 0

In [13]: ' PY 2015'.find('PY')
Out[13]: 1

Peut-être que ce serait une bonne idée de supprimer les espaces blancs, c'est-à-dire:

In [14]: '  PY 2015'.find('PY')
Out[14]: 2

In [15]: '  PY 2015'.strip().find('PY')
Out[15]: 0

Et ensuite si seulement l'année est intéressante, elle peut être extraite avec split, c'est-à-dire:

In [16]: '  PY 2015'.strip().split()[1]
Out[16]: '2015'
0
mac13k