Espressione regolare per ripulire i nomi
Ho due dataframe di nomi. Il dataframe è più lungo, ma sto usando top3 come esempi.
First list name examples:
JOSEPH W. JOHN
MIMI N. ALFORD
WANG E. Li
Second list name examples:
AAMIR, DENNIS M
MAHAMMED, LINDA X
ABAD, FARLEY J
Devo estrarre il primo nome in quei due dfs, come posso estrarli in un'unica espressione regolare.
The return should be
list 1
JOSHEPH
MIMI
WANT
list 2
DNNIES
LINDA
FARLEY
Il mio codice attuale sembra come re.search(r'(?<=,)\w+', df['name']), ma non ha restituito il nome corretto. È possibile scrivere due codici di espressioni regolari in Python per estrarre quei nomi?
Risposte
Sembra che ciò che si desidera cercare qui è la prima sequenza di caratteri di parola che non dispongono di un qualsiasi punto virgola dopo sulla linea, piuttosto che uno che non ha una virgola prima di esso. Quindi, invece di una tua affermazione positiva, sembra che vorrai un'affermazione negativa.
Prova a usare come regex:
r'\w+(?!.*,)'
Applicalo usando:
df['name'].apply(lambda name:re.search(r'\w+(?!.*,)',name).group())
Applicando quanto sopra a questo dataframe di esempio:
name foo
0 JOSEPH W. JOHN 1
1 MIMI N. ALFORD 3
2 WANG E. Li 3
3 AAMIR, DENNIS M 3
4 MAHAMMED, LINDA X 3
5 ABAD, FARLEY J 3
dà:
0 JOSEPH
1 MIMI
2 WANG
3 DENNIS
4 LINDA
5 FARLEY
Uso
df['First Name'] = df['name'].str.extract(r'(?:(?<=^(?!.*,))|(?<=, ))([A-Z]+)', expand=False)
Vedi la prova
Spiegazione
--------------------------------------------------------------------------------
(?: group, but do not capture:
--------------------------------------------------------------------------------
(?<= look behind to see if there is:
--------------------------------------------------------------------------------
^ the beginning of the string
--------------------------------------------------------------------------------
(?! look ahead to see if there is not:
--------------------------------------------------------------------------------
.* any character except \n (0 or more
times (matching the most amount
possible))
--------------------------------------------------------------------------------
, ','
--------------------------------------------------------------------------------
) end of look-ahead
--------------------------------------------------------------------------------
) end of look-behind
--------------------------------------------------------------------------------
| OR
--------------------------------------------------------------------------------
(?<= look behind to see if there is:
--------------------------------------------------------------------------------
, ', '
--------------------------------------------------------------------------------
) end of look-behind
--------------------------------------------------------------------------------
) end of grouping
--------------------------------------------------------------------------------
( group and capture to \1:
--------------------------------------------------------------------------------
[A-Z]+ any character of: 'A' to 'Z' (1 or more
times (matching the most amount
possible))
--------------------------------------------------------------------------------
) end of \1