Search code examples
javascriptjqueryregexcurrencynumber-formatting

Format positive and negative decimal numbers with jquery and regex


I found this code below at jsfiddle that, in my shitty opinion, is very nice. But it doesn't format negative numbers, only positive. I tried to modify it but my regex knowledge wasn't enough. Could anyone help me modify this to format positive and negative numbers?

$('#valor').keyup(function(){
    var v = $(this).val();
    v = v.replace(/\D/g,'');
    v = v.replace(/(\d{1,2})$/, ',$1');  
    v = v.replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1.');  
    v = v != '' ? 'R$ '+ v : '';
    $(this).val(v); 
});


Solution

  • You could just check and see if the value is negative when you start, and add the sign back in at the end:

    $('#valor').keyup(function(){
        let v = $(this).val();
        const neg = v.startsWith('-');
    
        v = v.replace(/[-\D]/g,'');
        v = v.replace(/(\d{1,2})$/, ',$1');
        v = v.replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1.');
    
        v = v != ''?'$ '+v:'';
        if(neg) v = '-'.concat(v);  // prepend the dash
    
        $(this).val(v);
    });
    

    jsfiddle


    EDIT: Here's a more "pure" regex solution:

    $('#valor').keyup(function(){
        let v = $(this).val();
    
        v = v.replace(/[^-\d]/g, '');
        v = v.replace(/(\d{1,2})$/g, ',$1');
        v = v.replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1.');
    
        v = v ? '$ ' + v : '';
        $(this).val(v);
    
    });
    

    jsfiddle

    Basically, in the first replace statement, you add '-' to the set of characters to not get replaced, i.e. everything that isn't a digit or a dash will get replaced by '' in this new version.