3. Nozioni di base su Python

3.1. Script [bases_01]: Operazioni di base
Lo script [bases_01] introduce le caratteristiche di base di Python.
Commenti
- riga 2: la parola chiave def definisce una funzione;
- riga 2: la funzione riceve il parametro [string]. Il tipo del parametro non è specificato. Python utilizza esclusivamente il passaggio per valore. Questo varia a seconda dei dati:
- per un tipo semplice (numero, booleano, ecc.), questo valore è il valore incapsulato dai dati (4, True, ecc.);
- per un tipo complesso (lista, classe, ecc.), questo valore è l'indirizzo dei dati;
- righe 3–4: il corpo della funzione. È indentato di un tabulatore a destra. È questa indentazione, combinata con il carattere : dell'istruzione def, che definisce il corpo della funzione. Questo vale per tutte le istruzioni con un corpo: if, else, while, for, try, except;
- riga 4: la sintassi utilizzata qui è [print('text1%F1text2%F2…' % data1, data2)]:
- i [%Fi] (qui %s) sono formati di visualizzazione:
- %s (stringa): per una stringa;
- %d (decimale): per interi decimali con segno;
- %f (float): formato decimale per i numeri reali;
- %e (esponenziale): formato esponenziale per un numero reale;
- …
- [data1, data2…] sono le espressioni i cui valori si desidera visualizzare:
- [data1] verrà visualizzato utilizzando il formato F1;
- [data2] verrà visualizzato utilizzando il formato F2;
- …
- riga 10: Python gestisce i tipi di variabili internamente. È possibile determinare il tipo di una variabile utilizzando la funzione type(variable), che restituisce una variabile di tipo 'type'. L'espressione '%s' % (type(variable)) è una stringa che rappresenta il tipo della variabile;
- riga 25: il programma principale. Di solito (ma non necessariamente) viene dopo la definizione di tutte le funzioni dello script. Il suo contenuto non è indentato;
- riga 28: In Python, le variabili non vengono dichiarate. Python distingue tra maiuscole e minuscole. La variabile `Nom` è diversa dalla variabile `nom`. Una stringa può essere racchiusa tra virgolette doppie " o virgolette singole '. È quindi possibile scrivere `'dupont'` o `"dupont"`;
- riga 34: c'è una differenza tra una tupla (1,2,3) (notare le parentesi) e una lista [1,2,3] (notare le parentesi quadre). Una tupla è immutabile, mentre una lista è mutabile. In entrambi i casi, l'elemento numero i è indicato come [i];
- Riga 40: range(n) è la tupla (0, 1, 2, …, n-1);
- riga 41: il formato %d viene utilizzato per i numeri interi con segno;
- riga 74: len(var) è il numero di elementi nella collezione var (tupla, lista, dizionario, ecc.);
- riga 84: la struttura [for in …] consente di iterare su una struttura iterabile. Liste e tuple sono elementi iterabili;
- riga 86: gli altri operatori booleani sono or e not;
- riga 93: somma i numeri maggiori di 0 presenti nella lista;
L'output sullo schermo è il seguente:
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_01.py
nom=dupont
liste[0]=un
liste[1]=deux
liste[2]=3
liste[3]=4
[chaine1,chaine2,chaine1chaine2]
chaine=chaine1
type[4]=<class 'int'>
type[chaine1]=<class 'str'>
type[['un', 'deux', 3, 4]]=<class 'list'>
type[a changé]=<class 'str'>
res1=14
(res1,res2,res3)=[un,0,100]
liste[0]=un
liste[1]=0
liste[2]=100
liste[0]=8
liste[1]=5
somme=13
Process finished with exit code 0
3.2. Script [bases_02]: Stringhe formattate
Python 3 ha introdotto un nuovo modo di formattare le stringhe:
La sintassi della stringa formattata è la seguente:
dove:
- [expr]: un'espressione;
- [formati]: il formato dell'espressione [expri]. Questi formati sono quelli del linguaggio C:
- %d: per i numeri interi;
- %f: notazione decimale per i numeri reali;
- %e: notazione esponenziale per i numeri reali;
- %s: per le stringhe di caratteri. Questo è il formato utilizzato quando non viene specificato alcun formato per [expr];
- %nd, %nf, %ns: visualizza [expri] su n caratteri: la stringa viene troncata o riempita con spazi;
- riga 7: [04d], numero intero di 4 caratteri riempito a sinistra con zeri;
- riga 11: [8.2f], numero decimale in virgola mobile di 8 caratteri con 2 cifre dopo la virgola;
- riga 12: [.3e], un numero in virgola mobile in forma esponenziale con 3 cifre decimali per la mantissa;
- riga 18: [20.10s], i primi 10 caratteri di una stringa riempiti con spazi per arrivare a 20 caratteri;
I risultati dell'esecuzione sono i seguenti:
3.3. Script [bases_03]: Conversioni di tipo
Qui ci concentriamo sulle conversioni di tipo che coinvolgono dati di tipo str (stringa), int (intero), float (virgola mobile) e bool (booleano).
Sono possibili molte conversioni di tipo. Alcune potrebbero fallire, come quelle alle righe 46–47, che tentano di convertire la stringa 'abc' in un numero intero. Abbiamo gestito l'errore utilizzando un blocco try/except. Una forma generale di questo blocco
è la seguente:
try:
actions
except Exception as ex:
actions
finally:
actions
Se una qualsiasi delle azioni nel blocco try genera un'eccezione (segnala un errore), il controllo salta immediatamente alla clausola except. Se le azioni nel blocco try non generano un'eccezione, la clausola except viene ignorata. Gli attributi Exception ed ex dell'istruzione except sono opzionali. Quando presenti, Exception specifica il tipo di eccezione intercettata dall'istruzione except, mentre ex contiene l'eccezione che si è verificata. È possibile avere più istruzioni except se si desidera gestire diversi tipi di eccezioni all'interno dello stesso blocco try.
L'istruzione finally è facoltativa. Se presente, le azioni nel blocco finally vengono sempre eseguite, indipendentemente dal fatto che si sia verificata o meno un'eccezione.
Torneremo sulle eccezioni più avanti.
Le righe 49–61 mostrano vari tentativi di convertire dati di tipo str, int, float e NoneType in booleani. Ciò è sempre possibile. Le regole sono le seguenti:
- bool(int i) è False se i è 0, True in tutti gli altri casi;
- bool(float f) restituisce False se f è 0.0, True in tutti gli altri casi;
- bool(str string) restituisce False se string contiene 0 caratteri, True in tutti gli altri casi;
- bool(None) restituisce False. None è un valore speciale che indica che la variabile esiste ma non ha alcun valore.
L'output sullo schermo è il seguente:
Si noti che tutti i dati sono oggetti, ovvero istanze di classe. Ciò significa che possono avere metodi. Questo è mostrato nelle righe 63–75 del codice. Qui non stiamo cercando di spiegare cosa fanno i metodi, ma semplicemente di mostrare che esistono.
3.4. Script [bases_04]: ambito delle variabili
Lo script [bases_04] mostra che Python non ha il concetto di variabili con ambito di blocco:
Risultati
Commenti
I risultati mostrano due cose:
- riga 4: la variabile [i] nel blocco [if] è la stessa della variabile i usata alla riga 2;
- riga 6: la variabile [j] è quella inizializzata nel blocco [if];
In alcuni linguaggi, dove le variabili vengono dichiarate, una variabile definita all'interno di un blocco (come quella nelle righe 3–5) non è conosciuta al di fuori di esso. In Python, non è così.
3.5. Script [bases_05]: Elenchi - 1
Lo script [bases_05] è il seguente:
Note:
- la notazione array[i:j] si riferisce agli elementi da i a j-1 dell'array;
- la notazione [i:] si riferisce all'elemento i e agli elementi successivi dell'array;
- la notazione [:i] si riferisce agli elementi da 0 a i-1 dell'array;
- riga 19: print (%s) % (list1) visualizza la stringa: "[ list1[0], list1[2]…, list1[n-1]]";
- riga 24: la notazione print ('f{list1}') fa la stessa cosa;
Risultati
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_05.py
list1 a 6 éléments
list1[0]=0
list1[1]=1
list1[2]=2
list1[3]=3
list1[4]=4
list1[5]=5
list1 a 6 éléments
0
10
2
3
4
5
[0, 10, 2, 3, 4, 5, 10, 11]
[0, 10, 2, 3, 4, 5]
[-10, -11, -12, 0, 10, 2, 3, 4, 5]
[-10, -11, -12, 100, 101, 0, 10, 2, 3, 4, 5]
[-10, -11, -12, 101, 0, 10, 2, 3, 4, 5]
Process finished with exit code 0
3.6. Script [bases_06]: liste - 2
Il codice precedente può essere scritto in modo diverso (bases_06) utilizzando alcuni metodi delle liste:
I risultati sono gli stessi della versione precedente.
3.7. script [bases_07]: il dizionario
Lo script [bases_07] mostra come definire e utilizzare un dizionario, talvolta chiamato array associativo.
Note:
- riga 11: la definizione hard-coded di un dizionario;
- riga 15: conjoints.items() restituisce l'elenco delle coppie (chiave, valore) dal dizionario conjoints;
- riga 20: conjoints.keys() restituisce le chiavi del dizionario conjoints;
- riga 25: conjoints.values() restituisce i valori del dizionario conjoints;
- riga 3: husband in spouses restituisce True se la chiave husband esiste nel dizionario spouses, False in caso contrario;
- riga 36: un dizionario può essere visualizzato su una singola riga.
Risultati
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_07.py
Nombre d'éléments du dictionnaire : 4
conjoints[Pierre]=Gisèle
conjoints[Paul]=Virginie
conjoints[Jacques]=Lucette
conjoints[Jean]=
liste des clés-------------
dict_keys(['Pierre', 'Paul', 'Jacques', 'Jean'])
liste des valeurs------------
dict_values(['Gisèle', 'Virginie', 'Lucette', ''])
La clé [Jacques] existe associée à la valeur [Lucette]
La clé [Lucette] n'existe pas
La clé [Jean] existe associée à la valeur []
Nombre d'éléments du dictionnaire : 3
{'Pierre': 'Gisèle', 'Paul': 'Virginie', 'Jacques': 'Lucette'}
type des clés : <class 'dict_keys'>
type des valeurs : <class 'dict_values'>
clés : <class 'list'>, ['Pierre', 'Paul', 'Jacques']
valeurs : <class 'list'>, ['Gisèle', 'Virginie', 'Lucette']
Process finished with exit code 0
Note:
- Si noti che alle righe 16–17 dei risultati, le chiavi e i valori di un dizionario non formano una lista ma un tipo 'dict_keys';
- righe 18–19: un semplice cast di tipo li converte in un tipo [list];
3.8. script [bases_08]: tuple
Una tupla è simile a una lista ma è immutabile:
Risultati
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_08.py
tuple1 a 6 elements
tuple1[0]=0
tuple1[1]=1
tuple1[2]=2
tuple1[3]=3
tuple1[4]=4
tuple1[5]=5
tuple1 a 6 elements
0
1
2
3
4
5
tuple1=(0, 1, 2, 3, 4, 5)
Traceback (most recent call last):
File "C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_08.py", line 19, in <module>
tuple1[0] = 10
TypeError: 'tuple' object does not support item assignment
Process finished with exit code 1
Note:
- Le righe 17-20 dell'output: mostrano che una tupla non può essere modificata.
3.9. Script [bases_09]: liste e dizionari multidimensionali
Lo script [bases_09] mostra come definire e utilizzare una lista o un dizionario multidimensionale:
Commenti
- riga 7: multi[i1] è una lista;
- riga 18: value è una lista;
Risultati
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_09.py
multi[0][0]=0
multi[0][1]=1
multi[0][2]=2
multi[1][0]=10
multi[1][1]=11
multi[1][2]=12
multi[1][3]=13
multi[2][0]=20
multi[2][1]=21
multi[2][2]=22
multi[2][3]=23
multi[2][4]=24
multi=[[0, 1, 2], [10, 11, 12, 13], [20, 21, 22, 23, 24]]
multi[zéro][0]=0
multi[zéro][1]=1
multi[un][0]=10
multi[un][1]=11
multi[un][2]=12
multi[un][3]=13
multi[deux][0]=20
multi[deux][1]=21
multi[deux][2]=22
multi[deux][3]=23
multi[deux][4]=24
multi={'zéro': [0, 1], 'un': [10, 11, 12, 13], 'deux': [20, 21, 22, 23, 24]}
Process finished with exit code 0
3.10. Script [bases_10]: Collegamenti tra stringhe e liste
Lo script [bases_10] mostra come estrarre elementi da una stringa separati da un delimitatore comune in un elenco.
Note:
- riga 3: il metodo `string.split(separator)` divide la stringa `string` in elementi separati dal separatore `separator` e li restituisce sotto forma di lista. Pertanto, l'espressione `'1:2:3:4'.split(":")` restituisce la lista (`'1', '2', '3', '4'`);
- riga 11: 'separator'.join(list) restituisce la stringa 'list[0]+separator+list[1]+separator+…'.
Risultati
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_10.py
<class 'list'>
liste a 4 éléments
liste=['1', '2', '3', '4']
chaine2=1:2:3:4
chaine=1:2:3:4:
liste a 5 éléments
liste=['1', '2', '3', '4', '']
chaine=1:2:3:4::
liste a 6 éléments
liste=['1', '2', '3', '4', '', '']
Process finished with exit code 0
3.11. Script [bases_11]: Espressioni regolari
Lo script [bases_11] mostra come utilizzare le espressioni regolari:
Note:
- Si noti il modulo [re] importato alla riga 2. Esso contiene le funzioni per la gestione delle espressioni regolari;
- riga 10: il confronto tra una stringa e un'espressione regolare (pattern) restituisce True se la stringa corrisponde al pattern, False in caso contrario;
- riga 12: match.groups() è una tupla i cui elementi sono le parti della stringa che corrispondono agli elementi dell'espressione regolare racchiusi tra parentesi. Nel pattern:
- ^.*?(\d+).*?, match.groups() sarà una tupla a un elemento perché c'è un solo set di parentesi;
- ^(.*?)(\d+)(.*?)$, match.groups() sarà una tupla a 3 elementi perché ci sono tre parentesi;
- riga 21: un'espressione regolare letterale è scritta come r"xxx". È il simbolo r che trasforma la stringa in un'espressione regolare;
Le espressioni regolari ci permettono di convalidare il formato di una stringa. Ad esempio, possiamo verificare che una stringa che rappresenta una data sia nel formato gg/mm/aa. Per farlo, usiamo un pattern e confrontiamo la stringa con quel pattern. In questo esempio, g, m e a devono essere cifre. Il modello per un formato di data valido è quindi "\d\d/\d\d/\d\d", dove il simbolo \d rappresenta una cifra. I simboli che possono essere utilizzati in un modello sono i seguenti:
Carattere | Descrizione |
\ | Indica il carattere seguente come carattere speciale o letterale. Ad esempio, "n" corrisponde al carattere "n", mentre "\n" corrisponde a un carattere di nuova riga. La sequenza "\\" corrisponde a "\", mentre "\(" corrisponde a "(". |
^ | Corrisponde all'inizio della stringa. |
$ | Corrisponde alla fine della stringa. |
* | Corrisponde al carattere precedente zero o più volte. Pertanto, "zo*" corrisponde a "z" o "zoo". |
+ | Corrisponde al carattere precedente una o più volte. Pertanto, "zo+" corrisponde a "zoo", ma non a "z". |
? | Corrisponde al carattere precedente zero o una volta. Ad esempio, "a?ve?" corrisponde a "ve" in "lever". |
. | Corrisponde a qualsiasi singolo carattere, eccetto il carattere di nuova riga. |
(pattern) | Cerca il pattern e memorizza la corrispondenza. La sottostringa corrispondente può essere recuperata dalla collezione match.groups(). Per trovare corrispondenze con caratteri all'interno di parentesi ( ), usa "\(" o "\)". |
x|y | Corrisponde a x o y. Ad esempio, "z|foot" corrisponde a "z" o "foot". "(z|f)oo" corrisponde a "zoo" o "foo". |
{n} | n è un numero intero non negativo. Trova esattamente n occorrenze del carattere. Ad esempio, "o{2}" non trova "o" in "Bob", ma trova le prime due "o" in "fooooot". |
{n,} | n è un numero intero non negativo. Trova almeno n occorrenze del carattere. Ad esempio, "o{2,}" non trova "o" in "Bob", ma trova tutte le "o" in "fooooot". "o{1,}" equivale a "o+" e "o{0,}" equivale a "o*". |
{n,m} | m e n sono numeri interi non negativi. Trova almeno n e al massimo m occorrenze del carattere. Ad esempio, "o{1,3}" trova le prime tre "o" in "foooooot" e "o{0,1}" è equivalente a "o?". |
[xyz] | Set di caratteri. Trova uno qualsiasi dei caratteri specificati. Ad esempio, "[abc]" trova "a" in "plat". |
[^xyz] | Insieme di caratteri negativo. Trova qualsiasi carattere non elencato. Ad esempio, "[^abc]" trova la "p" in "plat". |
[a-z] | Intervallo di caratteri. Corrisponde a qualsiasi carattere compreso nell'intervallo specificato. Ad esempio, "[a-z]" corrisponde a qualsiasi carattere alfabetico minuscolo compreso tra "a" e "z". |
[^m-z] | Intervallo di caratteri negativi. Trova qualsiasi carattere non compreso nell'intervallo specificato. Ad esempio, "[^m-z]" trova qualsiasi carattere non compreso tra "m" e "z". |
\b | Corrisponde a un confine di parola, ovvero alla posizione tra una parola e uno spazio. Ad esempio, "er\b" corrisponde a "er" in "lever", ma non a "er" in "verb". |
\B | Corrisponde a un confine che non rappresenta una parola. "en*t\B" corrisponde a "ent" in "bien entendu". |
\d | Corrisponde a un carattere che rappresenta una cifra. Equivalente a [0-9]. |
\D | Corrisponde a un carattere che non è una cifra. Equivalente a [^0-9]. |
\f | Corrisponde a un carattere di interruzione di riga. |
\n | Equivalente a un carattere di nuova riga. |
\r | Equivalente al carattere di ritorno a capo. |
\s | Corrisponde a qualsiasi carattere di spaziatura, inclusi spazio, tabulazione, interruzione di pagina, ecc. Equivalente a "[ \f\n\r\t\v]". |
\S | Corrisponde a qualsiasi carattere non spazio. Equivalente a "[^ \f\n\r\t\v]". |
\t | Corrisponde a un carattere di tabulazione. |
\v | Corrisponde a un carattere di tabulazione verticale. |
\w | Corrisponde a qualsiasi carattere che rappresenta una parola, compreso il trattino basso. Equivalente a "[A-Za-z0-9_]". |
\W | Corrisponde a qualsiasi carattere che non rappresenti una parola. Equivalente a "[^A-Za-z0-9_]". |
\num | Corrisponde a num, dove num è un numero intero positivo. Si riferisce alle corrispondenze memorizzate. Ad esempio, "(.)\1" corrisponde a due caratteri identici consecutivi. |
\n | Corrisponde a n, dove n è un valore di escape ottale. I valori di escape ottali devono essere composti da 1, 2 o 3 cifre. Ad esempio, "\11" e "\011" corrispondono entrambi a un carattere di tabulazione. "\0011" è equivalente a "\001" e "1". I valori di escape ottali non devono superare 256. In caso contrario, nell'espressione vengono prese in considerazione solo le prime due cifre. Consente l'uso dei codici ASCII nelle espressioni regolari. |
\xn | Corrisponde a n, dove n è un valore di escape esadecimale. I valori di escape esadecimali devono essere composti esattamente da due cifre. Ad esempio, "\x41" corrisponde a "A". "\x041" è equivalente a "\x04" e "1". Consente l'uso dei codici ASCII nelle espressioni regolari. |
Un elemento in un pattern può apparire una o più volte. Vediamo alcuni esempi che coinvolgono il simbolo \d, che rappresenta una singola cifra:
modello | significato |
\d | una cifra |
\d? | 0 o 1 cifra |
\d* | 0 o più cifre |
\d+ | 1 o più cifre |
\d{2} | 2 cifre |
\d{3,} | almeno 3 cifre |
\d{5,7} | da 5 a 7 cifre |
Ora immaginiamo un modello in grado di descrivere il formato previsto per una stringa:
stringa di destinazione | modello |
una data nel formato gg/mm/aa | \d{2}/\d{2}/\d{2} |
un'ora nel formato hh:mm:ss | \d{2}:\d{2}:\d{2} |
un numero intero senza segno | \d+ |
una sequenza di spazi, che può essere vuota | \s* |
un numero intero senza segno che può essere preceduto o seguito da spazi | \s*\d+\s* |
un numero intero che può essere con segno e preceduto o seguito da spazi | \s*[+|-]?\s*\d+\s* |
un numero reale senza segno che può essere preceduto o seguito da spazi | \s*\d+(.\d*)?\s* |
un numero reale che può essere con segno e preceduto o seguito da spazi | \s*[+-]?\s*\d+(.\d*)?\s* |
una stringa contenente la parola "just" | \bjuste\b |
È possibile specificare dove cercare il pattern nella stringa:
pattern | significato |
^motivo | il pattern inizia la stringa |
pattern$ | il pattern termina la stringa |
^pattern$ | il pattern inizia e termina la stringa |
pattern | il pattern viene cercato in qualsiasi punto della stringa, a partire dall'inizio. |
Modello ricercato | pattern |
una stringa che termina con un punto esclamativo | !$ |
una stringa che termina con un punto | \.$ |
una stringa che inizia con la sequenza // | ^// |
una stringa costituita da una singola parola, facoltativamente preceduta o seguita da spazi | ^\s*\w+\s*$ |
una stringa composta da due parole, facoltativamente seguita o preceduta da spazi | ^\s*\w+\s*\w+\s*$ |
una stringa contenente la parola secret | \bsecret\b |
I sottopattern di un pattern possono essere "estratti". Pertanto, non solo possiamo verificare che una stringa corrisponda a un particolare pattern, ma possiamo anche estrarre da quella stringa gli elementi corrispondenti ai sottopattern del pattern che sono stati racchiusi tra parentesi. Ad esempio, se analizziamo una stringa contenente una data nel formato dd/mm/yy e vogliamo estrarre le componenti dd, mm e yy di quella data, useremmo il modello (\d\d)/(\d\d)/(\d\d).
Risultati dello script
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_11.py
Résultats(xyz1234abcd,^.*?(\d+).*?$)
('1234',)
Résultats(12 34,^.*?(\d+).*?$)
('12',)
Résultats(abcd,^.*?(\d+).*?$)
La chaîne [abcd] ne correspond pas au modèle [^.*?(\d+).*?$]
Résultats(xyz1234abcd,^(.*?)(\d+)(.*?)$)
('xyz', '1234', 'abcd')
Résultats(12 34,^(.*?)(\d+)(.*?)$)
('', '12', ' 34')
Résultats(abcd,^(.*?)(\d+)(.*?)$)
La chaîne [abcd] ne correspond pas au modèle [^(.*?)(\d+)(.*?)$]
Résultats(10/05/97,^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$)
('10', '05', '97')
Résultats( 04/04/01 ,^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$)
('04', '04', '01')
Résultats(5/1/01,^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$)
La chaîne [5/1/01] ne correspond pas au modèle [^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$]
Résultats(187.8,^\s*([+-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$)
('', '187.8')
Résultats(-0.6,^\s*([+-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$)
('-', '0.6')
Résultats(4,^\s*([+-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$)
('', '4')
Résultats(.6,^\s*([+-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$)
('', '.6')
Résultats(4.,^\s*([+-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$)
('', '4.')
Résultats( + 4,^\s*([+-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$)
('+', '4')
Process finished with exit code 0