Sam Ccp
Sam Ccp

Reputation: 1162

How to get parameter value inside a string?

Here's a thing i've been trying to resolve...

We've got some data from an ajax call and the result data is between other stuff a huge string with key:value data. For example:

"2R=OK|2M=2 row(s) found|V1=1,2|"

Is it posible for js to do something like: var value = someFunction(str, param);

so if i search for "V1" parameter it will return "1,2"

I got this running on Sql server no sweat, but i'm struggling with js to parse the string.

So far i'm able to do this by a VERY rudimentary for loop like this:

var str = "2R=OK|2M=2 row(s) found|V1=1,2|";
var param = "V1";
var arr = str.split("|");
var i = 0;
var value = "";
for(i = 0; i<arr.length; ++i){
    if( arr[i].indexOf(param)>-1 ){
        value = arr[i].split("=")[1];
    }
}
console.log(value);

if i put that into a function it works, but i wonder if there's a more efficient way to do it, maybe some regex? but i suck at it. Hopefully somebody may shine a light on this for me?

Thanks!

Upvotes: 1

Views: 390

Answers (3)

Paul
Paul

Reputation: 141827

This should work for you and it's delimiters are configurable (if you wish to parse a similar string with different delimiters, you can just pass in the delimiters as arguments):

var parseKeyValue = (function(){

  return function(str, search, keyDelim, valueDelim){
    keyDelim = quote(keyDelim || '|');
    valueDelim = quote(valueDelim || '=');

    var regexp = new RegExp('(?:^|' + keyDelim + ')' + quote(search) + valueDelim + '(.*?)(?:' + keyDelim + '|$)');
    var result = regexp.exec(str);

    if(result && result.length > 1)
      return result[1];
  };

  function quote(str){
    return (str+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
  }
})();

Quote function borrowed form this answer

Usage examples:

var str = "2R=OK|2M=2 row(s) found|V1=1,2|";
var param = "V1";
parseKeyValue(str, param); // "1,2"

var str = "2R=OK&2M=2 row(s) found&V1=1,2";
var param = "2R";
parseKeyValue(str, param, '&'); // "OK"

var str = 
"2R=>OK\n\
2M->2 row(s) found\n\
V1->1,2";

var param = "2M";
parseKeyValue(str, param, '\n', '->'); // "2 row(s) found"

Upvotes: 1

kol
kol

Reputation: 28698

Here is another approach:

HTML:

<div id="2R"></div>
<div id="2M"></div>
<div id="V1"></div>

Javascript:

function createDictionary(input) {
    var splittedInput = input.split(/[=|]/),
        kvpCount = Math.floor(splittedInput.length / 2),
        i, key, value,
        dictionary = {};

    for (i = 0; i < kvpCount; i += 1) {
        key = splittedInput[i * 2];
        value = splittedInput[i * 2 + 1];
        dictionary[key] = value;
    }
    return dictionary;
}

var input = "2R=OK|2M=2 row(s) found|V1=1,2|",
    dictionary = createDictionary(input),
    div2R = document.getElementById("2R"),
    div2M = document.getElementById("2M"),
    divV1 = document.getElementById("V1");

div2R.innerHTML = dictionary["2R"];
div2M.innerHTML = dictionary["2M"];
divV1.innerHTML = dictionary["V1"];

Result:

OK
2 row(s) found
1,2

Upvotes: 0

David Thomas
David Thomas

Reputation: 253318

This seems to work for your specific use-case:

function getValueByKey(haystack, needle) {
    if (!haystack || !needle) {
        return false;
    }
    else {
        var re = new RegExp(needle + '=(.+)');
        return haystack.match(re)[1];
    }
}

var str = "2R=OK|2M=2 row(s) found|V1=1,2|",
    test = getValueByKey(str, 'V1');
console.log(test);

JS Fiddle demo.

And, to include the separator in your search (in order to prevent somethingElseV1 matching for V1):

function getValueByKey(haystack, needle, separator) {
    if (!haystack || !needle) {
        return false;
    }
    else {
        var re = new RegExp('\\' + separator + needle + '=(.+)\\' + separator);
        return haystack.match(re)[1];
    }
}

var str = "2R=OK|2M=2 row(s) found|V1=1,2|",
    test = getValueByKey(str, 'V1', '|');
console.log(test);

JS Fiddle demo.

Note that this approach does require the use of the new RegExp() constructor (rather than creating a regex-literal using /.../) in order to pass variables into the regular expression.

Similarly, because we're using a string to create the regular expression within the constructor, we need to double-escape characters that require escaping (escaping first within the string and then escaping within in the created RegExp).

References:

Upvotes: 2

Related Questions