2
votes

Javascript: remplacez tout sauf les nombres et n'autorisez qu'un seul point

Cela fonctionne pour les entiers, par exemple :

'123x'.replace(/\D/g, '')
'123'

Quelle expression régulière permettrait d'obtenir le même résultat, mais n'autorisant qu'un seul point? Exemples:

  • 1 -> 1
  • 1x -> 1
  • 10. -> 10.
  • 10.0 -> 10.0
  • 10.01 -> 10.01
  • 10.01x -> 10.01
  • 10.01. -> 10.01


4 commentaires

Que devrait-il se passer avec 10.01.23 => 10.01 ou 10.0123?


Et avec "a1b2c3d.e4f5g6h"?


10.0123 @ChristophHerold


123.456 @trincot


5 Réponses :


2
votes

Vous pouvez utiliser parseFloat et reconvertir en chaîne.

function convert(s) {
    return s.match(/^\d+\.?\d*/)[0];
}

console.log(['1', '1x', '10.', '10.0', '10.01', '10.01x', '10.01.'].map(convert));

Une approche avec une expression régulière.

console.log(parseFloat('10.01.x').toString());


1 commentaires

Pas de vote négatif. mais aucun des codes ne donne le résultat attendu. op veut que 10.01.23 soit 10.0123 et non 10.01



0
votes

let arr = ['1', '1x', '10.', '10.0', '10.01', '10.01x', '10.01.', '10.01.23', 'a1b2c3d.e4f5g6h'];

arr.forEach(val => {
	val = val.replace(/[^\d.]/g, '').match(/([0-9]+(\.[0-9]*)?)/);
	if (val) console.log(val[0]);
})

remplacer (/ [^ \ d.] / g, '') pour remplacer tout caractère non numérique et non . . p>

[0-9] + chiffres de 0 à 9 seront mis en correspondance, et + pour correspondra une ou plusieurs fois

. suivi d'un point.

[0-9] *? correspond à 0 à 9 (mais correspond à ZERO ou plus de temps)


0 commentaires

1
votes

Vous pouvez faire quelque chose comme ça, vous avez besoin de deux méthodes de remplacement:

  1. Pour tout supprimer sauf le chiffre et le point. Pour cela, utilisez la classe de caractères annulée `[^ \ d.].
  2. Pour supprimer les points en double, utilisez remplacer par un rappel lorsque nous devons remplacer le contenu après le premier point, utilisez donc \. ([. \ d] +) $ pour faire correspondre la chaîne entière après la première opération (y compris le point) et dans le rappel, supprimez tous les points restants de la valeur capturée (chaîne après le premier point).

var arr = ['1', '1x', '10.', '10.0', '10.01', '10.01x', '10.01.', '10.01.23', 'a1b2c3d.e4f5g6h'];

function format(str) {
  return str.replace(/[^\d.]/g, '').replace(/\.([.\d]+)$/, function(m, m1) {
    return '.' + m1.replace(/\./g, '')
  });
}

arr.forEach((v) => console.log(`${v} => ${format(v)}`))

DÉMO:

'123x'.replace(/[^\d.]/g, '').replace(/\.([.\d]+)$/,function(m,m1){
   return '.' + m1.replace(/\./g, '')
})


1 commentaires

Bon un pote +1



8
votes

Avec deux remplacements:

console.log("a12b3.1&23.0a2x".replace(/[^.\d]/g, '')
                             .replace(/^(\d*\.?)|(\d*)\.?/g, "$1$2"));

La première action supprimera tous les caractères autres que les chiffres et les points

Le deuxième remplacement correspond à des séquences de chiffres éventuellement suivies d'un point, mais il le fait de deux manières différentes. Lorsqu'une telle séquence se produit au début de la chaîne, le point optionnel est placé à l'intérieur du premier groupe de capture, tandis que pour toutes les autres correspondances, le point est extérieur au (deuxième) groupe de capture.

Il existe deux groupes de capture, mais pour une correspondance donnée, un seul d'entre eux aura réellement du contenu. Ainsi, le contenu capturé peut être reproduit dans les deux cas avec $ 1 $ 2 . Cela inclura le premier point, mais en exclura tout autre.


0 commentaires

1
votes

UPDATE

Pourquoi ne pas simplement le faire à l'ancienne:

function formatNumber(s) {
    return s.replace(/[^\d\.]/g, '').replace(/\.(([^\.]*)\.)*/g, '.$2');
}
var inputs = ['10.01.x23.5asd6', '10.', '10', '.12vx12.1f53', '10.10.'];
for (var i = 0; i < inputs.length; i++) {
  console.log(formatNumber(inputs[i]));
}

Ne nécessite qu'une seule itération de la chaîne, donc vous n'obtiendrez probablement pas une meilleure durée d'exécution.

ANCIENNE RÉPONSE, NE FONCTIONNE PAS p>

Cela devrait également fonctionner (mais ce n'est pas le cas, merci à trincot de l'avoir signalé):

    function formatNumber(s) {
        var hadDot = false, result = '';
        for (var i = 0; i < s.length; i++) {
            var c = s[i];
            if (c >= '0' && c <= '9')
              result += c;
            else if (!hadDot && c == '.') {
              hadDot = true;
              result += c;
            }
        }
        return result;
    }
    var inputs = ['10.01.x23.5asd6', '10.', '10', '.12vx12.1f53', '10.10.'];
    for (var i = 0; i < inputs.length; i++) {
      console.log(formatNumber(inputs[i]));
    }

Tout d'abord, remplacez tous les non-chiffres et points. Ensuite, capturez tout après le premier point et remplacez-le par tout ce qui n'est pas un point. Mais, il a besoin d'une expression régulière en deux étapes.


2 commentaires

Vous avez perdu des chiffres lors du premier test. Le problème se produit lorsque l'entrée a 3 points ou plus.


Pour l'ancienne réponse en boucle +1