Monday, February 7, 2011

Javascript text manipulation

Just starting with js, decided to convert Friendfeed to a fluid app, and as part of that I need to be able to parse some numbers out of a string.

How do I complete this function?

function numMessages(text) {

    MAGIC HAPPENS (POSSIBLY THE DARK ART OF THE REGEX)

    return number;
}

input would be "Direct Messages (15)"

output would be 15.

Instincts tell me to find the first bracket then find the last bracket, and get the text in between but I don't know how to do that. Second instinct tells me to regex for [0-9], but I don't know how to run regexes in js. Jquery is avaliable already if needed.

Thanks!

  • This should do it:

    >>> 'Direct Messages (15)'.match(/[0-9]+/g);
    ["15"]
    

    Just be careful if you expect more than 1 number to be in the string:

    >>> 'Direct 19 Messages (15)'.match(/[0-9]+/g);
    ["19", "15"]
    

    If you only wanted the first match, you could remove the g flag:

    >>> 'Direct 19 Messages (15)'.match(/[0-9]+/);
    ["19"]
    

    If you only wanted to match what's between the parentheses

    >>> 'Direct 19 Messages (15)'.match(/\((.*?)\)/);
    ["(15)","15"] 
    // first index will always be entire match, 2nd index will be captured match
    

    As pointed out in the comments, to get the last match:

    >>> var matches = 'Direct 19 Messages (15)'.match(/[0-9]+/g);
    >>> matches[matches.length-1];
    "15"
    

    Though some boundary checking would also be appropriate. :)

    Rich Bradshaw : Good work! Thanks!
    Paolo Bergantino : That's an array, so you probably want to get [0] from match.
    Nosredna : Looking at his example, I think it's most likely he'd want the last number. He could put the answer into an array "arr" and use arr[arr.length-1].
    Paolo Bergantino : Thanks Nosredna, I forgot to give that example. Fixed.
    Nosredna : Good. :-) Of course the real danger is that the string he's scanning changes in some unpredictable way. But there's only so much you can do to future-proof the scanning of an alien string.
    Peter Bailey : @Paolo: great answer. I added a pattern case, hope you don't mind.
    Paolo Bergantino : @Peter Bailey: not at all, thanks for improving it.
    Rich Bradshaw : This sort of answer is why this website is so incredibly useful.
  • var reg = new RegExp('[0-9]+');
    reg.exec('Direct Messages (15)');
    
  • function numMessages(text) {
      return text.match(/\d+/g);
    }
    

    This will return all numbers (\d is a special character class equivalent to [0-9]) from the string. the /g makes the regex engine do a global search, thereby returning an array of all matches; if you just want one, remove the /g. Regardless of if your expression is global or not, match returns an array, so you will need to use array notation to get at the element you want.

    Note that results from a regular expression match are of type string; if you want numbers, you can use parseInt to convert "15" to 15.

    Putting that all together, if you just want one number, as it seems to appear from your initial question text:

    function numMessages(text) {
      return parseInt(text.match(/\d+/)[0]);
    }
    
    str = "Direct Messages (15)";
    numMessages(str); // 15
    

0 comments:

Post a Comment