3

I want to be able to extract all numbers (including floating point) from a string in JavaScript.

"-5. -2 3.1415 test 2.4".match(...) 

returns

["-2", "3.1415", "2.4"]

So far I have /[-+]?(\d*\.?\d+)/g, but this seems to return 5 along with the other numbers. I want to avoid that since in the string the "word" is 5. and not 5 or 5.0. Any hints?

victormejia
  • 1,174
  • 3
  • 12
  • 30
  • 2
    What about things like `.5`? Are both sides of the decimal point mandatory if it is there? – Martin Ender Nov 30 '12 at 00:01
  • -1 because your question problem statement and data do not agree. Please be consistent and precise. Also, I am "quite certain" this has been done numerous times before .. –  Nov 30 '12 at 00:01
  • @pst: His problem is that he doesn't want '5.' to be recognized as a valid number. It's your understanding that doesn't match the problem statement. – slebetman Nov 30 '12 at 03:16
  • 'match(...) .. *returns* ["-2", "3.1415", "2.4"]' .. 'So far I have /[-+]?(\d*\.?\d+)/g, but this seems to return 5 along with the other numbers.' If you understand this better, consider updating the question. –  Nov 30 '12 at 04:15

4 Answers4

2

If you want to not include the dot, a look-ahead would make sense:

/[-+]?\d*(\.(?=\d))?\d+/g

Another option is to move the second \d+ inside the parentheses:

/[-+]?\d+(\.\d+)?/g
Rob W
  • 341,306
  • 83
  • 791
  • 678
1

This rx gets numbers represented in strings, with or without signs, decimals or exponential format-

rx=/[+-]?((.\d+)|(\d+(.\d+)?)([eE][+-]?\d+)?)/g

String.prototype.getNums= function(){
    var rx=/[+-]?((\.\d+)|(\d+(\.\d+)?)([eE][+-]?\d+)?)/g,
    mapN= this.match(rx) || [];
    return mapN.map(Number);
};

var s= 'When it is -40 degrees outside, it doesn\'t matter that '+

'7 roses cost $14.35 and 7 submarines cost $1.435e+9.';

s.getNums();

/* returned value: (Array) -40, 7, 14.35, 7, 1435000000 */

kennebec
  • 102,654
  • 32
  • 106
  • 127
1

The reason this question is difficult to answer is you need to be able to check that the character before the number or before the + or - is either a whitespace or the start of the line.

As JavaScript does not have the ability to lookbehind a solution for this by using the .match() method on a string becomes nearly impossible. In light of this here is my solution.

var extractNumbers = (function ( ) {
    numRegexs = [
            /( |^)([+-]?[0-9]+)( |$)/g,
            /( |^)([+-]?[0-9]+\.[0-9]+)( |$)/g,
            /( |^)([+-]?[0-9]+\.[0-9]+([eE][+-])?[0-9]+)( |$)/g
    ];

    return function( str ) {

        var results = [], temp;

        for( var i = 0, len = numRegexs.length; i < len; i++ ) {

            while( temp = numRegexs[i].exec( str ) ) {
                results.push( temp[2] );
            }
        }

        return results;
    }
}( ));

The regular expressions in the numRegexs array correspond to integers, floats and exponential numbers.

Demo here

Bruno
  • 5,772
  • 1
  • 26
  • 43
0

Given that your example string has spaces between the items, I would rather do:

var tokens = "-5. -2 3.1415 test 2.4".split(" ");
var numbers = [];
for( var i = 0 ; i < tokens.length ; i++ )
  if( isNumber( tokens[i]) )
    numbers.push( tokens[i]*1 );
//numbers array should have all numbers

//Borrowed this function from here:
//http://stackoverflow.com/questions/18082/validate-numbers-in-javascript-isnumeric
function isNumber(n) {
  return !isNaN(parseFloat(n*1)) && isFinite(n*1) && !endsWith(n,".");
}

endsWith = function( s , suffix ) {
  return s.indexOf(suffix, s.length - suffix.length) !== -1;
};
tomdemuyt
  • 4,572
  • 2
  • 31
  • 60