Transform a formatted currency amount into a double value by utilizing regex

I need to convert various currency formats into a double value. For example:

  1. 1,000,000.00 => 1000000.00
  2. 2'345',00 => 2345.00
  3. 2'344'334.03 => 1000000.03

    The current solution I have is functional but inefficient. I am exploring options for using regex to make the conversion process more efficient.

        decimalPlace = amount[amount.length - 3];
    
    if (decimalPlace === '.' && amount.indexOf(',') < -1 && amount.indexOf("'") < -1) {
        return amount
    }
    if (decimalPlace === ',' && amount.indexOf("'") < -1) {
        value = amount.split('.').join('')
            .replace(',', '.')
        return value
    }
    if (decimalPlace === '.' && amount.indexOf(',') > -1) {
        value = amount.split(',').join('')
        return value
    }
    
    if (decimalPlace === ',' && amount.indexOf("'") > -1) {
        value = amount.split("'").join('')
            .replace(',', '.')
        return value
    }
    if (decimalPlace === '.' && amount.indexOf("'") > -1) {
        value = amount.split("'").join('')
        return value
    }
    return amount
    

If you have any suggestions on how to improve this process, please let me know.

Answer №1

You may have overcomplicated this solution. If the only supported formats are the ones listed, consider using a simplified function like the one below:

var value1 = "1,000,000.00";
var value2 = "2'345',00";
var value3 = "2'344'334.03";
var value4 = "2,00"

function formatValue(str){
    if(str.replace(/[^,]/g, "").length === 1){ // Only one comma present.
        str = str.replace(",", ".");
    }
    return parseFloat(str.replace(/[^0-9\.]/g, "")).toFixed(2);
}

[value1, value2, value3, value4].forEach(val => console.log(formatValue(val)));

EDIT: Added support for values with only one comma.

EDIT 2: Simplified the solution further:

var value1 = "1,000,000.00";
var value2 = "2'345',00";
var value3 = "2'344'334.03";
var value4 = "2,00"

function formatValue(str){
    if(str.replace(/[^,]/g, "").length === 1){ // Only one comma present.
        str = str.replace(",", ".");
    }
    return parseFloat(str.replace(/[^0-9\.]/g, "")).toFixed(2);
}

[value1, value2, value3, value4].forEach(val => console.log(formatValue(val)));

Answer №2

It's not advisable to heavily rely on regular expressions in this scenario. My approach would be divided into 2 steps.

Firstly, determine the correct decimal point based on the locale. This can easily be achieved by creating a function that adds a localized decimal point and returns it.

function findDecimalPoint(locale) {
    return (1.2).toLocaleString(locale).replace(/\d+/g, "");
}

The advantage of this function is that if no locale is provided, the default one will be used (which is "en-GB" in my case).

Now that you have identified the decimal point, you can use it to split the formatted number into two parts - the whole numbers before the decimal and the decimals after it.

function convertNumber(number, locale) {

    // Splitting the number based on the decimal point.
    var numberParts = String(number).split(findDecimalPoint(locale));

    // Removing all non-numeric characters from the whole numbers and parsing
    // them as a number.
    var converted = Number(numberParts[0].replace(/\D+/g, ""));

    // Checking for decimals. If present, converting them into
    // a decimal and adding them to the converted result.
    var decimals = numberParts[1];

    if (decimals && decimals.length) {
        converted += decimals / Math.pow(10, decimals.length);
    }

    return converted;

}

To use this function, simply input your numbers.

convertNumber("1,000,000.00"); // -> 1000000
convertNumber("2'345',00", "fr"); // -> 2345
convertNumber("2'344'334.03"); // -> 2344344.03
// I am aware these numbers are not formatted in French, but feel free to adjust 
// the format as needed.

function findDecimalPoint(locale) {
    return (1.2).toLocaleString(locale).replace(/\d+/g, "");
}

function convertNumber(number, locale) {

    var numberParts = String(number).split(findDecimalPoint(locale));
    var converted = Number(numberParts[0].replace(/\D+/g, ""));
    var decimals = numberParts[1];

    if (decimals && decimals.length) {
        converted += decimals / Math.pow(10, decimals.length);
    }

    return converted;
    
}

console.log(convertNumber("1,000,000.00"));
console.log(convertNumber("2'345',00", "fr"));
console.log(convertNumber("2'344'334.03"));

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for sending JSON data to .js files

I am experiencing an issue here. In locations.php, I have the following code to generate JSON data: <?php $locations = array( array('2479 Murphy Court', "Minneapolis, MN 55402", "$36,000", 48.87, 2.29, "property-detail.html", ...

Only switch a radio button when the Ajax call results in success

Within an HTML form, I am working with a group of Radio buttons that trigger an Ajax call when the onchange() event is fired. This Ajax call communicates with the server to process the value sent by the call. The response can either be a string of "succes ...

It seems that the JavaScript object is producing varied values in distinct locations despite no alterations made in between

I've encountered a puzzling issue where a variable is returning different values within a function, despite no modifications being made to it. This problem arises in a form component created using Vue.js (v2) that triggers a Vuex action. While I beli ...

Show a pop-up notification when the mouse passes over a word in the text

I've been grappling with this issue for days now and could really use some guidance. Despite scouring the web, I'm unsure if I've approached it correctly. What I'm trying to achieve is having an alert box pop up each time a user hovers ...

Invoke the jquery plugin upon completion of the HTML load via Ajax

For my current project, I needed to style input radio buttons and decided to use the jquery uniform plugin. However, the radio buttons are displayed after some Ajax content is loaded onto the page. Since I do not have permission to edit the form or Ajax ...

Center your attention on an AngularJS-created input element

I'm currently working on a todo list project using AngularJS and I am wondering if there is a method to automatically focus on an input box after creating it by clicking on a button. As of now, the save function in my controller looks like this: $sc ...

What is the best way to remove a div card along with its content in a React application?

https://i.sstatic.net/IlXwE.gif Encountering an issue similar to the gif image provided. Upon deleting the first card, the content of the subsequent card is also removed. How can this be prevented? state = { data: '', todoCard: [ ...

What is the syntax for implementing the 'slice' function in React?

While working on my React app, I encountered an issue when trying to extract the first 5 characters from a string using slice. The error message displayed was: TypeError: Cannot read property 'slice' of undefined I am utilizing a functional compo ...

What is the best method for initializing the value of ng-model as an empty string in AngularJS?

I need help setting the initial value for an attribute in my model. Here's the code I'm using: <input type="text" ng-model="selectedModel.title" name="title" value="" > What I want is for the attribute value to be initially set as an empt ...

Is it necessary to enable validation for an Angular reactive form toggle?

Can you help with this issue I'm having? I have a radio button that asks the user if they have a massage certificate. If they answer yes, a file input should be displayed. By default, the file input should not be required, but if the user selects yes, ...

Chrome does not properly support the clip() method in HTML5 canvas when rotation is used

When using a clip region on a canvas, I encountered an issue where it stops working as soon as the coordinate system is rotated by any non-zero value: window.onload = function() { var canvas = document.getElementById("mainCanvas"); var ct ...

Including an element to a React list

I am struggling to figure out how to add a new fruit to the existing list of fruits. Currently, when I submit, it just adds an empty string li to the list. Can someone help me with this issue? Here is my fruit list component: import AddFruit from '. ...

Trouble with radio button selection using onclick event in Bootstrap

I've been attempting to implement an onclick event with radio buttons in Bootstrap, but unfortunately the event isn't triggering. Here's the code I'm using: <input type="checkbox" onclick="alert('Scenery!')"/> However, ...

Is it possible for me to retrieve data in object using double v-for?

I am attempting to create a dynamic table using the following objects: <tr v-for="product in allPosts" :key="product.id"> <td v-for='(item, i) in checked' :key='`item${i}`'>{{product.item}}</td> </tr> In th ...

AngularJS Component enthusiasts

While going through a tutorial on the Angular UI Router GitHub page (link: https://github.com/angular-ui/ui-router), I came across an intriguing code snippet: var myApp = angular.module('myApp', ['ui.router']); // For Component users, ...

Error: The call stack exceeded the maximum size due to an unidentified cause

Just a quick note: I managed to fix the issue by now, but I'm curious to understand why it occurred initially: I've been working on retrieving data from mongoDB using mongoose. The code was running smoothly 99% of the time, but for some reason, ...

If the div is devoid of content, then remove the class

<div class="slider">content goes here</div> <div id="slider-2" class="active inactive">also some content here</div> <script type="text/javascript"> function checkEmpty( element ){ return !$.trim(element.html()) ...

Manipulate the url bar using ajax and window.location

When making an AJAX request using .load, everything works perfectly. However, there is an issue with the URL bar. I am trying to change the URL displayed in the bar. For instance, when the ajax loads the about/contact page, I want the URL bar to show about ...

Elevate javascript

How can I create a new constructor that will alert the increment value? Any suggestions on how to achieve this? This is the current code snippet: var increment = new Increment(); alert(increment); /* 1 */ alert(increment); /* 2 */ alert(increment + incr ...

The first parameter needs to be either a string, a buffer instance, or a uint8array. Null received

Encountering an error with my Node.js code and I'm not sure how to fix it. The error message reads: "First argument must be of type string or an instance of buffer or uint8array. Received undefined" I admit that I am new to Node.js and would apprecia ...