Discussion:
conversion string->decimal
(trop ancien pour répondre)
Olivier Berquin
2008-02-21 14:27:19 UTC
Permalink
Bonjour tout le monde,

C'est ma première intervention ici.
J'ai recherché dans les anciens messages et n'ait pas trouvé de
solution...

J'ai un formulaire dans lequel l'utilisateur doit encoder un montant
(decimal).
Mon input est au format texte.
Comment puis-je être certain d'avoir un type decimal?

j'ai fait ceci, mais ça me paraît un peu tiré par les cheveux:
$val1 = $montant + 0.001;
$val2 = $val1 - 0.001;
if ($val2 == 0)
{
// Ce n'est pas un nombre...
}

Merci.

Oli.
Olivier Miakinen
2008-02-21 17:50:41 UTC
Permalink
Bonjour,
Post by Olivier Berquin
J'ai un formulaire dans lequel l'utilisateur doit encoder un montant
(decimal).
Mon input est au format texte.
Comment puis-je être certain d'avoir un type decimal?
$val1 = $montant + 0.001;
$val2 = $val1 - 0.001;
if ($val2 == 0)
{
// Ce n'est pas un nombre...
}
Tu as la fonction is_numeric() :
http://fr2.php.net/manual/fr/function.is-numeric.php

Mais j'ai l'impression que ça ne te conviendra pas, car d'après ton code
tu sembles supposer que 0 n'est pas un montant décimal acceptable, même
s'il est écrit sous la forme « 0.000 ».

Tu peux aussi ragarder du côté des expressions rationnelles, par exemple
un truc du genre '/^[0-9]+\.[0-9]+$/' mais là encore il faudrait d'abord
que tu définisses précisément ce que tu veux accepter et ce que tu veux
rejeter.
Olivier Berquin
2008-02-22 09:26:29 UTC
Permalink
Attention, ma donnée $montant vient d'un formulaire.
Je ne peut donc pas utiliser les is_numéric, gettype et autres.
Ma donnée est du type "string".
Par contre, sur <http://www.php.net/manual/fr/function.is-
numeric.php>, j'ai vu une fonction qui utilise les expressions
régulière...
La voici:
<?
function my_is_numeric($value) {
$american = preg_match ("/^(-){0,1}([0-9]+)(,[0-9][0-9][0-9])*([.]
[0-9]){0,1}([0-9]*)$/" ,$value) == 1;
$world = preg_match ("/^(-){0,1}([0-9]+)(.[0-9][0-9][0-9])*([,]
[0-9]){0,1}([0-9]*)$/" ,$value) == 1;
return ($american or $world);
}
?>

-the English/American way of writing a float million number:
1,000,000.00
-the global way of writing a float million number: 1.000.000,02

Merci de m'avoir montrer la voie.

Oli.
P'tit Marcel
2008-02-22 10:03:31 UTC
Permalink
Post by Olivier Berquin
Attention, ma donnée $montant vient d'un formulaire.
Je ne peut donc pas utiliser les is_numéric, gettype et autres.
Ma donnée est du type "string".
Essaye et tu verras que c'est pourtant tout à fait possible car php
n'est pas un langage typé. La limitation est que les nombres décimaux
doivent utiliser un point décimal et non une virgule.
Post by Olivier Berquin
Par contre, sur <http://www.php.net/manual/fr/function.is-
numeric.php>, j'ai vu une fonction qui utilise les expressions
régulière...
function my_is_numeric($value) {
$american = preg_match ("/^(-){0,1}([0-9]+)(,[0-9][0-9][0-9])*([.]
[0-9]){0,1}([0-9]*)$/" ,$value) == 1;
$world = preg_match ("/^(-){0,1}([0-9]+)(.[0-9][0-9][0-9])*([,]
[0-9]){0,1}([0-9]*)$/" ,$value) == 1;
return ($american or $world);
}
Oui, cela règle le problème de la virgule décimale. Cela dit,
l'instruction peut être simplifiée/améliorée comme suit :

$world = preg_match('/^-?[0-9]+([.\s][0-9]{3})*(,[0-9]+)?$/' ,$value);

nota bene:
1/ le signe ? est une abréviation de {0,1}
2/ les groupes de 1000 sont ici séparables avec un espace (le \s) ou un
point, voire n'être pas séparés
3/ il vaut mieux mettre les masques entre simple quote (le ')
4/ le "== 1" à la fin est inutile


eça
--
P'tit Marcel
stats sur les forums modérés http://www.centrale-lyon.org/ng/
Olivier Berquin
2008-02-22 14:25:47 UTC
Permalink
Je vais bidouiller une expression régulière.
J'ai aussi testé l'exemple de Thomas, mais c'est un peu trop rigide:
n'accepte ni les espaces ni les virgules comme séparateur de millier.

Merci, donc, à tous.

Oli.
Olivier Miakinen
2008-02-22 14:25:47 UTC
Permalink
Post by Olivier Berquin
Attention, ma donnée $montant vient d'un formulaire.
Je ne peut donc pas utiliser les is_numéric, gettype et autres.
Ma donnée est du type "string".
Justement, il n'y a pas de problème pour ça avec is_numeric (sans
accent) : <http://fr2.php.net/manual/fr/function.is-numeric.php>.

<cit.>
bool is_numeric (mixed $var)
... Les chaînes numériques ...
Retourne TRUE si var est un nombre ou *une chaîne numérique*
</cit.>
Post by Olivier Berquin
Par contre, sur <http://www.php.net/manual/fr/function.is-
numeric.php>, j'ai vu une fonction qui utilise les expressions
régulière...
Et tu penses qu'elle fait ce que tu veux qu'elle fasse ? Sais-tu au
moins ce qu'elle teste ?
Post by Olivier Berquin
<?
function my_is_numeric($value) {
$american = preg_match ("/^(-){0,1}([0-9]+)(,[0-9][0-9][0-9])*([.]
[0-9]){0,1}([0-9]*)$/" ,$value) == 1;
Cette expression est équivalente à la suivante :
/^-?[0-9]+(,[0-9][0-9][0-9])*([.][0-9])?[0-9]*$/

Elle acceptera donc « -00000,000,001 » mais pas « 1. » ni « .01 ».
Post by Olivier Berquin
$world = preg_match ("/^(-){0,1}([0-9]+)(.[0-9][0-9][0-9])*([,]
[0-9]){0,1}([0-9]*)$/" ,$value) == 1;
Celle-ci est équivalente à :
/^-?[0-9]+(.[0-9][0-9][0-9])*(,[0-9])?[0-9]*$/

Elle acceptera « -0A000$000&000,1 » mais pas « 1. » ni « .01 ».
Post by Olivier Berquin
return ($american or $world);
Il reste à savoir ce que deviendra la valeur quand tu voudras utiliser
« -0A000$000&000,1 » ou « -00000,000,001 » comme un nombre (bon, là
c'est 0, mais avec « 1E027$000&000,1 » ça devrait donner 10^27...)
Post by Olivier Berquin
Merci de m'avoir montrer la voie.
Encore une fois, si tu décris précisément la syntaxe que tu veux
accepter et ce que tu veux rejeter, il sera alors possible d'écrire
une expression rationnelle adaptée à ton besoin.
Olivier Berquin
2008-02-22 15:38:20 UTC
Permalink
voici ce que j'ai fait:

function my_is_numeric($value)
{
$valeur = preg_match('/^[-\+]?[0-9]+([ .\s]?[0-9]{3})*([ ,.\s]?
[0-9])*?$/' ,$value);
return ($valeur);
}

Je suis assez large: j'accepte aussi bien le notation US que la FR (et
même un mélange des 2 -- hum).
Bon, je vous l'accorde, ce n'est pas trop "catholique". Mais c'est
pour l'intranet d'une petite société (15 personnes), et l'encodage de
ces montants n'incombera qu'à 3 personnes maximum.
Et il y a un une étape de confirmation...
Voici ce qui est accepté:
21 252,00
21.252,00
+21252,00
12 521,252.12 (ha ? ben oui... ça marche).
-0
+0
0
0,0
0.0
Ce qui ne l'est pas: dès qu'il y a un caractère autre qu'un chiffre...

Merci à tous pour votre aide.


Oli.
Olivier Miakinen
2008-02-22 16:09:45 UTC
Permalink
Post by Olivier Berquin
function my_is_numeric($value)
{
$valeur = preg_match('/^[-\+]?[0-9]+([ .\s]?[0-9]{3})*([ ,.\s]?
[0-9])*?$/' ,$value);
L'expression est équivalente à :
/^[-+]?[0-9]+([.\s]?[0-9]{3})*([,.\s]?[0-9])*$/

En effet,
1) Il est inutile d'échapper le + dans une classe de caractères
2) Le \s inclut déjà l'espace
3) Puisque ta chaîne est « ancrée » à gauche et à droite (^...$) il
est inutile de se préoccuper de « gourmandise » des répétitions (*?)

Et en fait, vu qu'un ([.\s]?[0-9]{3}) correspond à trois ([,.\s]?[0-9])
ton expression est même équivalente à :
/^[-+]?[0-9]+([,.\s]?[0-9])*$/
Post by Olivier Berquin
return ($valeur);
}
Je suis assez large: j'accepte aussi bien le notation US que la FR (et
même un mélange des 2 -- hum).
Bon, je vous l'accorde, ce n'est pas trop "catholique". Mais c'est
pour l'intranet d'une petite société (15 personnes), et l'encodage de
ces montants n'incombera qu'à 3 personnes maximum.
Et il y a une étape de confirmation...
Même s'il y a une étape de confirmation, je pense qu'une syntaxe plus
rigoureuse ne ferait pas de mal, et éviterait aux trois personnes en
question de s'interroger sur ta santé mentale.
Post by Olivier Berquin
21 252,00
21.252,00
+21252,00
12 521,252.12 (ha ? ben oui... ça marche).
-0
+0
0
0,0
0.0
Et aussi : 3,4.5,7 et 3.4,5.7
Combien valent ces nombres ? Quelque chose entre 3,4 et 3,5 ou quelque
chose entre 34,5 et 34,6 ?
Post by Olivier Berquin
Ce qui ne l'est pas: dès qu'il y a un caractère autre qu'un chiffre...
Voici une suggestion :

$valeur = str_replace(",", ".", $valeur);
$valeur = preg_replace("/[\s]/", "", $valeur);
if (preg_match('/^[+-]?[0-9]*\.[0-9]*$/, $valeur)) {
// Ok
}

Tu pourrais même remplacer le preg_replace par :
$valeur = preg_replace("/[^0-9.]/", "", $valeur);
Olivier Miakinen
2008-02-22 16:19:36 UTC
Permalink
Post by Olivier Miakinen
if (preg_match('/^[+-]?[0-9]*\.[0-9]*$/, $valeur)) {
Pardon, il y a une petite erreur ici car le . devient obligatoire.
Ce serait plutôt :
/^[+-]?[0-9]*\.?[0-9]*$/

Ou, en tenant compte de la remarque de Mickael :
/^[+-]?\d*\.?\d*$/

En revanche, je ne suis pas d'accord avec Mickael sur la nécessité de
remplacer « / » par « @ » quand il n'y a pas de « / » dans l'expression.
D'autant plus que pour d'autres types de contrôles il pourrait très bien
y avoir un « @ » (pour une adresse de courriel par exemple).
Olivier Berquin
2008-02-23 09:13:54 UTC
Permalink
Vous avez raison. Je ne suis pas assez rigoureux.
Merci aussi de penser à ma santé mentale ;-)

Je vais donc réviser tout ça!

Merci de mettre le doigt sur ces faiblesses (mes faiblesses).

Oli.
Mickael Wolff
2008-02-25 14:29:50 UTC
Permalink
Post by Olivier Miakinen
En revanche, je ne suis pas d'accord avec Mickael sur la nécessité de
D'autant plus que pour d'autres types de contrôles il pourrait très bien
Certes, en pratique je n'utilises jamais arobase. Je lui préfère
l'antiquote « ` ». Mais @ est plus lisible pour l'exemple :) Et puis
c'est une question de goût, de cohérence, et de praticité. C'était juste
pour dire d'éviter le slash, car ça donne rapidement des expressions
indigestes.
--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Olivier Miakinen
2008-02-25 15:55:41 UTC
Permalink
Post by Mickael Wolff
Post by Olivier Miakinen
En revanche, je ne suis pas d'accord avec Mickael sur la nécessité de
D'autant plus que pour d'autres types de contrôles il pourrait très bien
Certes, en pratique je n'utilises jamais arobase.
;-)
Post by Mickael Wolff
[...] C'était juste pour dire d'éviter le slash, car ça donne rapidement
des expressions indigestes.
Eh bien je ne suis *vraiment* pas d'accord avec ça.

Personnellement j'utilise toujours le slash quand il n'y a pas de slash
dans l'expression, car c'est le caractère le plus fréquemment employé à
cet usage, par exemple dans sed, vi ou JavaScript, et c'est pour cette
raison le plus lisible.

Bien sûr, quand il y a ne serait-ce qu'un slash dans l'expression, alors
je n'utilise jamais le slash comme délimiteur, et je choisis parmi la
centaine de caractères autorisés¹ celui qui me paraît le plus pertinent.
Cela peut-être '|' ou '`' s'ils ne sont pas utilisés, mais cela pourrait
tout aussi bien être ':' ou '='. Par ailleurs, je ne l'ai encore jamais
fait, mais je pourrais bien utiliser l'une des paires (), {}, [], et <>,
autorisées depuis PHP 4.0.4.

En fait, je trouve formidable que, alors que la syntaxe nous offre une
immense liberté de choix pour éviter les caractères d'échappement, on
puisse vouloir restreindre cette liberté en déconseillant l'utilisation
d'un délimiteur donné, et en particulier celui qui est utilisé de la
façon la plus universelle !

D'où mon coup de gueule. Note que mon opinion à ce sujet n'est guère
différente de celle concernant l'utilisation des guillemets doubles pour
les chaînes PHP, les variables à l'intérieur, et les guillemets simples
pour les attributs HTML².


Cordialement néanmoins,
--
Olivier Miakinen

(¹) Je me limite malgré tout au répertoire us-ascii pour éviter des
problèmes entre Latin1 et UTF-8 par exemple.

(²) Exemple :
"<a href='$url'>" contre "<a href=\"$url\">" ou '<a href="'.$url.'">'
Olivier Miakinen
2008-02-25 16:30:00 UTC
Permalink
[...] je choisis parmi la centaine de caractères autorisés¹ celui qui
me paraît le plus pertinent.
[...]
(¹) Je me limite malgré tout au répertoire us-ascii pour éviter des
problèmes entre Latin1 et UTF-8 par exemple.
Vérification faite, il n'y a pas une centaine de caractères autorisés
quand on s'interdit autre chose que us-ascii, mais une trentaine tout
au plus. J'avais cru naïvement que les caractères alphanumériques en
faisaient partie, même s'il ne me serait pas venu à l'idée de choisir
l'un d'entre eux comme délimiteur. Quoi qu'il en soit, ça ne change
rien à mon opinion (et à mon coup de gueule).
Olivier Berquin
2008-02-26 16:33:47 UTC
Permalink
Voici ma fonction:
function my_is_numeric($valeur)
{
$is_num = preg_match('/^[+-]?[0-9]*[,\.]*[0-9]*$/', $valeur);
return ($is_num);
}


Et voici un petit tableau avec quelques exemples de valeurs acceptées
ou refusées (en rouge):
<http://olivier.berquin.free.fr/job/test_montant>

Auriez-vous la gentillesse de me dire si c'est assez rigoureux sans
être trop rigide?

Merci pour tous vos précieux conseils...

Oli.
P'tit Marcel
2008-02-26 20:06:07 UTC
Permalink
Post by Olivier Berquin
$is_num = preg_match('/^[+-]?[0-9]*[,\.]*[0-9]*$/', $valeur);
Mes remarques à 2 roupies :
- il est inutile d'échapper le point dans une classe donc [,.]
- contrairement aux premières versions, ce masque ne permet pas de
séparateurs de milliers (sauf pour les nombres entiers inférieurs à un
million)

a+
--
P'tit Marcel
stats sur les forums modérés http://www.centrale-lyon.org/ng/
P'tit Marcel
2008-03-02 10:23:51 UTC
Permalink
Post by P'tit Marcel
- contrairement aux premières versions, ce masque ne permet pas de
séparateurs de milliers (sauf pour les nombres entiers inférieurs à un
million)
Une remarque en passant : il est faux de croire que toutes les cultures
séparent les chiffres en milliers. Par exemple, les indiens (d'Inde)
utilisent parfois des séparateurs tous les deux chiffres :

cent mille = 1 "Lakh" = 1,00,000
un milliard = 1 "Arab" = 1,00,00,00,000

Les chinois utilisent parfois des séparateurs tous les 4 chiffres
(ça doit être vrai car je l'ai lu sur internet).

Par ailleurs, le Révéré SI (Système International d'unité) précise
que le séparateur des milliers Ne Doit Pas Être un . ou une ,
Mais Seulement Un Espace
(voir http://www.bipm.org/utils/common/pdf/si_brochure_8_fr.pdf page 48)

Bon, j'admets que ces précisions sont d'un usage limité dans nos
régions, mais ça vous donnera peut-être un succès d'estime devant la
machine à café :-)
--
P'tit Marcel
stats sur les forums modérés http://www.centrale-lyon.org/ng/
Olivier Miakinen
2008-03-02 19:57:35 UTC
Permalink
Post by P'tit Marcel
Une remarque en passant : il est faux de croire que toutes les cultures
séparent les chiffres en milliers. Par exemple, les indiens (d'Inde)
cent mille = 1 "Lakh" = 1,00,000
un milliard = 1 "Arab" = 1,00,00,00,000
Oui, les Pakistanais aussi.
Post by P'tit Marcel
Les chinois utilisent parfois des séparateurs tous les 4 chiffres
(ça doit être vrai car je l'ai lu sur internet).
C'est vrai, mais je ne suis pas sûr que cela s'applique aux chiffres
(que nous nommons) arabes.
Post by P'tit Marcel
Par ailleurs, le Révéré SI (Système International d'unité) précise
que le séparateur des milliers Ne Doit Pas Être un . ou une ,
Mais Seulement Un Espace
Absolument. J'irais même jusqu'à préciser « une » espace « insécable ».
Post by P'tit Marcel
(voir http://www.bipm.org/utils/common/pdf/si_brochure_8_fr.pdf page 48)
Merci pour le lien.
Guillaume
2008-03-03 11:27:27 UTC
Permalink
Les chinois utilisent parfois des séparateurs tous les 4 chiffres (ça
doit être vrai car je l'ai lu sur internet).
Les japonais aussi. Techniquement, ce n'est pas non plus un "léger"
argument je pense :)
--
Guillaume
Olivier Berquin
2008-03-03 14:36:33 UTC
Permalink
Post by P'tit Marcel
Par ailleurs, le Révéré SI (Système International d'unité) précise
que le séparateur des milliers Ne Doit Pas Être un . ou une ,
Mais Seulement Un Espace
(voirhttp://www.bipm.org/utils/common/pdf/si_brochure_8_fr.pdfpage 48)
Très intéressant comme lien, si ce n'est qu'il n'y est pas question de
séparateur de milliers, mais bien de séparateur décimal.
Et Olivier Miakinen chipote sur les mots... mais il a (presque)
entièrement raison.
Il faut utiliser une espace fine insécable pour séparer les milliers
(et je sais de quoi je parle, pour une fois: je suis metteur en page).

Oli.
P'tit Marcel
2008-03-03 17:14:12 UTC
Permalink
Post by Olivier Berquin
Post by P'tit Marcel
(voirhttp://www.bipm.org/utils/common/pdf/si_brochure_8_fr.pdfpage 48)
Très intéressant comme lien, si ce n'est qu'il n'y est pas question de
séparateur de milliers, mais bien de séparateur décimal.
Ben si :

"D'après la 9e Conférence générale (1948, Résolution 7) et la 22e
Conférence générale (2003, Résolution 10), les nombres comportant un
grand nombre de chiffres peuvent être partagés en tranches de trois
chiffres, séparées par un espace, afin de faciliter la lecture. Ces
tranches ne sont jamais séparées par des points, ni par des virgules.
Cependant, lorsqu'il n'y a que quatre chiffres avant ou après le
séparateur décimal, il est d'usage de ne pas isoler un chiffre par un
espace. L'habitude de grouper ainsi les chiffres est question de choix
personnel ; elle n'est pas toujours suivie dans certains domaines
spécialisés tels que le dessin industriel, les documents financiers et
les scripts qui doivent être lus par ordinateur."

Au passage, le document parle aussi "d'UN espace" donc je ne suis pas
seul à faire l'erreur :-)
--
P'tit Marcel
stats sur les forums modérés http://www.centrale-lyon.org/ng/
Olivier Berquin
2008-03-04 14:27:37 UTC
Permalink
Post by Olivier Berquin
Très intéressant comme lien, si ce n'est qu'il n'y est pas question de
séparateur de milliers, mais bien de séparateur décimal.
"D'après la 9e Conférence générale (1948, Résolution 7) et la 22e [...]
Je n'avais lu que les titres... Pardon.
Au passage, le document parle aussi "d'UN espace" donc je ne suis pas
seul à faire l'erreur :-)
Je sais... il faut travailler dans la typographie pour "savoir" qu'il
y a une différence entre ces deux espaces.
Et même les gens du métier font l'erreur...


J'en profite pour réitérer mes remerciements. Vos conseils sont
précieux. Merci à tous, encore et encore.

Oli.
Olivier Miakinen
2008-03-03 17:14:12 UTC
Permalink
Post by Olivier Berquin
Il faut utiliser une espace fine insécable pour séparer les milliers
(et je sais de quoi je parle, pour une fois: je suis metteur en page).
Tu as raison, j'ai omis de préciser « fine » parce que nous discutons
dans un groupe où l'immense majorité des réponses concerne l'affichage
par un outil commun tel qu'un navigateur web sur un ordinateur person-
nel, or jusqu'à présent le support de l'espace fine dans ce genre d'en-
vironnement est quasi inexistant.

Au fait, je sais aussi (un peu) de quoi je parle car je me suis docu-
menté avant de commettre ceci :
http://www.miakinen.net/vrac/nombres#chiffres

Cette page est d'ailleurs en cours de réécriture, principalement au
sujet des rectifications de 1990. Mais si quelqu'un a des informations
à propos d'une éventuelle séparation en chinois ou en japonais des
chiffres *arabes* par groupes de quatre, cela m'intéresse aussi.
Guillaume
2008-03-03 20:39:10 UTC
Permalink
Post by Olivier Miakinen
Cette page est d'ailleurs en cours de réécriture, principalement au
sujet des rectifications de 1990. Mais si quelqu'un a des informations
à propos d'une éventuelle séparation en chinois ou en japonais des
chiffres *arabes* par groupes de quatre, cela m'intéresse aussi.
Pour le japonais, les groupements se font simplement par 4 zéros

1 = ichi
10 = ju
100 = hyaku
1000 = sen
1 0000 = ichi man

10 0000 = ju man
100 0000 = hyaky man
...
1 0000 0000 = ichi oku
1 0000 0000 0000 = (ic)choo

2 5236 = ni man go sen ni hyaku san ju roku
(2: ni, 3: san, 5: go, 6: roku)

A ton service.
--
Guillaume
Olivier Miakinen
2008-03-04 14:27:37 UTC
Permalink
Post by Guillaume
Post by Olivier Miakinen
Cette page est d'ailleurs en cours de réécriture, principalement au
sujet des rectifications de 1990. Mais si quelqu'un a des informations
à propos d'une éventuelle séparation en chinois ou en japonais des
chiffres *arabes* par groupes de quatre, cela m'intéresse aussi.
Pour le japonais, les groupements se font simplement par 4 zéros
Par quatre zéros *quand ils l'écrivent en chiffres arabes* ?
Post by Guillaume
1 = ichi
10 = ju
100 = hyaku
1000 = sen
1 0000 = ichi man
10 0000 = ju man
100 0000 = hyaky man
...
1 0000 0000 = ichi oku
1 0000 0000 0000 = (ic)choo
2 5236 = ni man go sen ni hyaku san ju roku
(2: ni, 3: san, 5: go, 6: roku)
Je viens de trouver une page disant explicitement l'inverse :
http://en.wikipedia.org/wiki/Japanese_numerals#Large_numbers
<cit.>
However, numbers written in Arabic numerals are separated by commas
every three digits following Western convention.
</cit.>
(le caractère séparateur étant une virgule dans les exemples donnés).

Alors, qui a raison ? Et où faire suivre la discussion pour qu'elle soit
en charte ?
Guillaume
2008-03-04 20:38:05 UTC
Permalink
Post by Olivier Miakinen
Par quatre zéros *quand ils l'écrivent en chiffres arabes* ?
[...]
Alors au temps pour moi, je ne pense pas avoir raison vis à vis de
l'écriture arabe, je n'ai songé qu'au système de comptage "standard"
(oral donc).
--
Guillaume
Matthieu Moy
2008-03-04 14:27:37 UTC
Permalink
Post by Guillaume
Post by Olivier Miakinen
Cette page est d'ailleurs en cours de réécriture, principalement au
sujet des rectifications de 1990. Mais si quelqu'un a des informations
à propos d'une éventuelle séparation en chinois ou en japonais des
chiffres *arabes* par groupes de quatre, cela m'intéresse aussi.
Pour le japonais, les groupements se font simplement par 4 zéros
Y'a aussi la version indienne, où on sépare les trois derniers, et les
autres par paquets de 2 :

100
1 000
10 000
1 00 000 (alias "one lack")
10 00 000
1 00 00 000 (alias "one crore")
--
Matthieu
Olivier Miakinen
2008-02-26 21:54:51 UTC
Permalink
[ Je remets le titre d'origine car on revient à la question initiale ]
Post by Olivier Berquin
function my_is_numeric($valeur)
{
$is_num = preg_match('/^[+-]?[0-9]*[,\.]*[0-9]*$/', $valeur);
return ($is_num);
}
Et voici un petit tableau avec quelques exemples de valeurs acceptées
<http://olivier.berquin.free.fr/job/test_montant>
Voici un autre exemple de valeur acceptée que je ne vois pas dans ton
tableau : "8,.,.,.,.3".
Post by Olivier Berquin
Auriez-vous la gentillesse de me dire si c'est assez rigoureux sans
être trop rigide?
Tout d'abord, comme pour le + et ainsi que l'a déjà signalé P'tit
Marcel, il est inutile d'échapper le . dans une classe de caractères.

Ensuite, et surtout, tu ne nous as pas dit quel traitement tu faisais
sur la valeur une fois qu'elle a été acceptée. J'avais supposé qu'elle
allait servir à faire des calculs, et qu'au final elle devait être
conforme à la syntaxe des flottants en PHP (donc pas d'espace ni de
virgule dedans). Or tu ne fais apparemment aucune transformation pour
remplacer une virgule par un point décimal, et P'tit Marcel semble
regretter que ta dernière proposition n'ait plus de séparateurs de
milliers...


Si vraiment tu veux faire des calculs avec ces nombres, alors il me
semble qu'il faudrait :
1) définir d'abord clairement la syntaxe que tu veux accepter (et la
*documenter* pour les utilisateurs qui devront faire la saisie) ;
2) écrire le code permettant de contrôler cette syntaxe. Il est possible
d'être un peu plus souple en éliminant silencieusement certains
caractères non prévus, en particulier les espaces avant et après ;
3) si la syntaxe en question n'est pas compatible avec celle de PHP,
écrire le code permettant la traduction dans un sens, mais aussi
dans l'autre sens, afin de présenter à l'utilisateur une syntaxe
qui corresponde, à l'affichage aussi, à ce que tu as documenté.

Et attention de ne pas placer la charrue avant les bœufs, c'est-à-dire
se préoccuper des points (2) et (3) avant d'avoir complètement résolu
le (1).
Olivier Berquin
2008-02-28 08:39:21 UTC
Permalink
Post by Olivier Miakinen
Ensuite, et surtout, tu ne nous as pas dit quel traitement tu faisais
sur la valeur une fois qu'elle a été acceptée.
Oups.
Quel c...
En gros (en très gros, même), je fais une espèce d'intranet de
"gestion" des jobs au sein de notre entreprise. Je travaille en PHP
avec des tables en MySQL.
Concernant le "problème" de vérification d'un montant: il s'agit d'un
petit formulaire pour encoder diverses données sur une facture (par
rapport à un job).
L'utilisateur encode donc son montant dans un champ "text".
J'écris ensuite ces données dans ma db.

Merci pour la remarque "8,.,.,.,.3"
J'ai modifié ma fonction comme suit:
function my_is_numeric($valeur)
{
$is_num = preg_match('/^[+-]*[0-9]*[,.]?[0-9]*$/', $valeur);
return ($is_num);
}


Oli.
P'tit Marcel
2008-02-28 13:31:40 UTC
Permalink
Post by Olivier Berquin
Concernant le "problème" de vérification d'un montant: il s'agit d'un
petit formulaire pour encoder diverses données sur une facture (par
rapport à un job).
L'utilisateur encode donc son montant dans un champ "text".
J'écris ensuite ces données dans ma db.
ok donc les séparateurs de milliers ne sont pas les bienvenus.
Post by Olivier Berquin
function my_is_numeric($valeur)
{
$is_num = preg_match('/^[+-]*[0-9]*[,.]?[0-9]*$/', $valeur);
____________________________________^

AMHA, il reste une erreur : remplace le premier * par un ?
tel que tu l'as écrit, la fonction autoriserait la saisie de
++----++34.3 par exemple

Par ailleurs, ta fonction acceptera une absence de saisie (chaîne vide)
voire la saisie d'un signe tout seul (+ - . ,) ce qui n'est peut être
pas ce que tu veux.

NB: après une classe de caractère []
* veut dire "un nombre quelconque de fois, ou pas du tout"
? veut dire "une fois, ou pas du tout"
+ veut dire "un nombre quelconque de fois"


eça
--
P'tit Marcel
stats sur les forums modérés http://www.centrale-lyon.org/ng/
Olivier Miakinen
2008-02-28 15:45:31 UTC
Permalink
Post by P'tit Marcel
ok donc les séparateurs de milliers ne sont pas les bienvenus.
Ouf, je n'aurai pas à me castagner avec PM !
Olivier Berquin
2008-02-29 13:55:50 UTC
Permalink
Merci pour tous vos éclaircissements.

Concernant la chaîne vide, ce n'est pas trop un problème.

Oli.

NB On a, pour une fois, évité une "guerre de codes" ;-)
Olivier Miakinen
2008-02-28 13:31:40 UTC
Permalink
Post by Olivier Berquin
Post by Olivier Miakinen
Ensuite, et surtout, tu ne nous as pas dit quel traitement tu faisais
sur la valeur une fois qu'elle a été acceptée.
En gros (en très gros, même), je fais une espèce d'intranet de
"gestion" des jobs au sein de notre entreprise. Je travaille en PHP
avec des tables en MySQL.
Concernant le "problème" de vérification d'un montant: il s'agit d'un
petit formulaire pour encoder diverses données sur une facture (par
rapport à un job).
Mais cette donnée particulière, elle sert juste à l'affichage (auquel
cas "3,99" sera probablement mieux compris en français que "3.99") ou
bien elle sert à des calculs (auquel cas "3,99" risque de se transformer
en "3") ? Quand je te demandais quel traitement tu faisais sur cette
valeur, je voulais dire « quel code PHP pour transformer la chaîne en
nombre " ?

En outre, si tu acceptes aussi bien la virgule que le point en entrée,
est-ce que tu gardes ça à l'affichage, d'où risque de confusion ?
Post by Olivier Berquin
function my_is_numeric($valeur)
{
$is_num = preg_match('/^[+-]*[0-9]*[,.]?[0-9]*$/', $valeur);
return ($is_num);
}
Mêmes questions, donc.
P'tit Marcel
2008-02-26 16:33:47 UTC
Permalink
Post by Olivier Miakinen
Post by Mickael Wolff
[...] C'était juste pour dire d'éviter le slash, car ça donne rapidement
des expressions indigestes.
Eh bien je ne suis *vraiment* pas d'accord avec ça.
Personnellement j'utilise toujours le slash quand il n'y a pas de slash
dans l'expression, car c'est le caractère le plus fréquemment employé à
cet usage, par exemple dans sed, vi ou JavaScript, et c'est pour cette
raison le plus lisible.
Hé bien je ne suis *vraiment* pas d'accord avec ton *vrai* désaccord ;-)

Un masque est déjà assez difficile à lire, autant ne pas le borner par
des caractères imposants par la taille et qui cachent l'essentiel, à
savoir les classes de caractères [], les sous-masques () et autres
assertions ?< ?=. Par ailleurs, on parle d'un délimiteur et les
délimiteurs de loin les plus fréquents en programmation sont les
guillemets simples ou doubles. L'antiguillemet simple ` est une
approximation proche de ces délimiteurs habituels. La preuve que c'est
un bon choix, c'est que c'est le caractère que j'utilise dans les
masques preg_*** !

Le vrai scandale est qu'il soit nécessaire d'employer un délimiteur. Le
premier paramètre des fonctions preg_** correspond en réalité à deux
propriétés qui n'ont rien à voir entre elles: d'une part le masque et
d'autre part les modificateurs. Dans tout langage digne de ce nom, ces
propriétés seraient transmises dans deux paramètres distincts.

c'étaient mes deux yuans.

a+
--
P'tit Marcel
stats sur les forums modérés http://www.centrale-lyon.org/ng/
Olivier Miakinen
2008-02-26 21:54:51 UTC
Permalink
Post by P'tit Marcel
Hé bien je ne suis *vraiment* pas d'accord avec ton *vrai* désaccord ;-)
:-D
Post by P'tit Marcel
Un masque est déjà assez difficile à lire, autant ne pas le borner par
des caractères imposants par la taille et qui cachent l'essentiel, à
savoir les classes de caractères [], les sous-masques () et autres
assertions ?< ?=.
Ce n'est pas faux. D'ailleurs je n'ai pas très envie à priori d'utiliser
[] et (). En revanche, {} me semblerait un assez bon choix à la place de
// (quand aucun des deux n'est dans l'expression, bien sûr).
Post by P'tit Marcel
Par ailleurs, on parle d'un délimiteur et les
délimiteurs de loin les plus fréquents en programmation sont les
guillemets simples ou doubles. L'antiguillemet simple ` est une
approximation proche de ces délimiteurs habituels. La preuve que c'est
un bon choix, c'est que c'est le caractère que j'utilise dans les
masques preg_*** !
Je n'ai pas dit non plus que l'accent grave ` était un mauvais
délimiteur, hein ! Sauf bien sûr s'il fait partie de l'expression
rationnelle.
Post by P'tit Marcel
Le vrai scandale est qu'il soit nécessaire d'employer un délimiteur. Le
premier paramètre des fonctions preg_** correspond en réalité à deux
propriétés qui n'ont rien à voir entre elles: d'une part le masque et
d'autre part les modificateurs. Dans tout langage digne de ce nom, ces
propriétés seraient transmises dans deux paramètres distincts.
Alors là je ne peux qu'approuver sans réserve.

Cordialement,
--
Olivier
P'tit Marcel
2008-02-28 08:39:21 UTC
Permalink
Post by Olivier Miakinen
Alors là je ne peux qu'approuver sans réserve.
Ouf, je n'aurais pas à ma castagner avec OM !
--
P'tit Marcel
BertrandB
2008-03-07 09:46:02 UTC
Permalink
Post by Olivier Miakinen
Post by Mickael Wolff
[...] C'était juste pour dire d'éviter le slash, car ça donne rapidement
des expressions indigestes.
Eh bien je ne suis *vraiment* pas d'accord avec ça.
Personnellement j'utilise toujours le slash quand il n'y a pas de slash
dans l'expression, car c'est le caractère le plus fréquemment employé à
cet usage, par exemple dans sed, vi ou JavaScript, et c'est pour cette
raison le plus lisible.
Bien sûr, quand il y a ne serait-ce qu'un slash dans l'expression, alors
je n'utilise jamais le slash comme délimiteur, et je choisis parmi la
centaine de caractères autorisés¹ celui qui me paraît le plus pertinent.
Cela peut-être '|' ou '`' s'ils ne sont pas utilisés, mais cela pourrait
tout aussi bien être ':' ou '='. Par ailleurs, je ne l'ai encore jamais
fait, mais je pourrais bien utiliser l'une des paires (), {}, [], et <>,
autorisées depuis PHP 4.0.4.
je vais abonder en corrigeant ... lorsque le / me semble alourdir
j'utilise le ? qui dans certaines version d'ed (notamment sous GCOS6) à
un sens (/ match l'expression suivante ? match l'expression précédente)
Mickael Wolff
2008-02-22 16:09:45 UTC
Permalink
Post by Olivier Berquin
function my_is_numeric($value)
{
$valeur = preg_match('/^[-\+]?[0-9]+([ .\s]?[0-9]{3})*([ ,.\s]?
[0-9])*?$/' ,$value);
return ($valeur);
}
Si déjà tu utilises \s, utilises \d : ça simplifie. Et un conseil :
évites d'utiliser / comme délimiteur d'expression, échapper des / à gogo
peut vite devenir pénible.

'@^[-\+]?[\d]+([ .\s]?[\d]{3})*([ ,.\s]?[\d])*?$@'
--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
CrazyCat
2008-02-21 17:50:40 UTC
Permalink
Post by Olivier Berquin
J'ai un formulaire dans lequel l'utilisateur doit encoder un montant
(decimal).
Mon input est au format texte.
Comment puis-je être certain d'avoir un type decimal?
is_float($montant) peut surement t'aider.
--
Réseau IRC Francophone: http://www.zeolia.net
Aide et astuces webmasters : http://www.c-p-f.org
Communauté Francophone sur les Eggdrops: http://www.eggdrop.fr
Paul
2008-02-21 17:50:41 UTC
Permalink
Post by Olivier Berquin
Bonjour tout le monde,
...
Post by Olivier Berquin
Mon input est au format texte.
Comment puis-je être certain d'avoir un type decimal?
RTFM :
http://www.php.net/manual/fr/function.is-numeric.php
Guillaume Grason
2008-02-21 17:50:41 UTC
Permalink
Post by Olivier Berquin
Comment puis-je être certain d'avoir un type decimal?
Bonjour,
Vous pouvez faire une vérification avec is_numeric
- http://fr.php.net/is_numeric

La fonction intval est aussi intéressante pour traiter directement des
entiers en zappant la vérification (si ce n'est pas un nombre alors le
retour de intval sera de 0)
- http://fr.php.net/intval

Cordialement,
--
Guillaume Grason
Thomas Mlynarczyk
2008-02-21 17:50:41 UTC
Permalink
Post by Olivier Berquin
J'ai un formulaire dans lequel l'utilisateur doit encoder un montant
(decimal).
Mon input est au format texte.
Comment puis-je être certain d'avoir un type decimal?
$montant
= is_numeric( $montant )
? (float) $montant
: 0.0;
--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Continuer la lecture sur narkive:
Loading...