I have dataframe and i wand to extract some localisation on the text using regex. I have to extract three values and create three new columns. I can't match the first occurrence in the text. I must always take the locations before the dashes in text exemple.
df["Auto localisation 1"]=df["Description"].str.extract(r"Localisation[\s]*:([^\n].*)\n")
df["Auto localisation 2"]=df["Description"].str.extract("Localisation[\s]*:.*\n([^_\n]*)\n[^\n]*\n_ ")
df["Auto localisation 3"]=df["Description"].str.extract("Localisation[\s]*:.*\n[^_\n]*\n([^\n_]*)\n")
exemple of strong texttext is below:
reference de piece
27.10.2020 08:49:49 JEAN BAPTISTE DAIGREMONT (ijuplo) Tél. 00
Localisation:TRAIN
PRINCIPAL GAUCHE
______________________________
Non-conformité 0001 :
Type de non-conf. : Absence couleur/peinture, pigmentation
VISITE AVION AVANT PEINTURE
Nous constatons qu'il manque du bleu
metallo sur les cosses des tresses de masses ainsi
que du gris sous les rivets suite à notre demande
de reprise.
Localisation : Sous les trappes "porte feuille
G/D"
Voir exemple en PJ.
Flamme toujours en place.
Demandons interventions pour remise en état.
______________________________
Moment de Détection: Lors de l'inspection
ouput expected:
Auto localisation 1=TRAIN
Auto localisation 2=GAUCHE
Auto localisation 3=(empty) because in this exemple there is not localisation 3
My code give as result:
Auto localisation 1=TRAIN
Auto localisation 2=GAUCHE
Auto localisation 3=Voir exemple en PJ
How can result this problem? thks
CodePudding user response:
For your 3 patterns, you can start the match from the start of the string, and do not cross matching lines that either start with Localisation: or only underscores using a negative lookahead.
\A(?:(?![^\S\n]*Localisation:|[^\S\n]*_ \n).*\n)*[^\S\n]*Localisation[\s]*:([^\n].*)\n
\A(?:(?![^\S\n]*Localisation:|[^\S\n]*_ \n).*\n)*[^\S\n]*Localisation[\s]*:.*\n([^_\n]*)\n[^\n]*\n
\A(?:(?![^\S\n]*Localisation:|[^\S\n]*_ \n).*\n)*[^\S\n]*Localisation[\s]*:.*\n[^_\n]*\n([^\n_]*)\n
Regex demo 1 | Regex demo 2 | Regex demo 3
Or with a single regex and 3 named capture groups:
\A(?:(?![^\S\n]*Localisation:|[^\S\n]*_ \n).*\n)*[^\S\n]*Localisation\s*:(?P<Auto_localisation_1>[^\n].*)(?:\n[^\S\n]*(?!Localisation:)(?P<Auto_localisation_2>[^\s_].*)(?:\n[^\S\n]*(?!Localisation:)(?P<Auto_localisation_3>[^\s_].*))?)?