anuiq
anuiq

Reputation: 119

get key value pairs out from the string javascript

If my string looks like this

"<First key="ab" value="qwerty"/>
<First key="cd" value="asdfg"/>
<First key="ef" value="zxcvb"/>"

and I want to get data out in the format

ab:"qwerty" cd:"asdfg" ef:"zxcvb"

How should I write the JS ?

Upvotes: 1

Views: 5898

Answers (4)

user663031
user663031

Reputation:

Your input is a kind of XML. The best way is to treat it as such. We will parse it as XML, but to do so, we need to first wrap it in a root element:

var str = "<Root>" + input + "</Root>"

We parse it with

var parser = new DOMParser();
var dom = parser.parseFromString(str, "text/xml");

Get the document element (Root):

var docelt = dom.documentElement;

Now we can loop over its children and build our result, using standard DOM access interfaces like getAttribute:

var result = {};
var children = docelt.children;
for (var i = 0; i < children.length; i++) {
  var child = children[i];
  result[child.getAttribute('key')] = child.getAttribute('value');
}

> result
< Object {ab: "qwerty", cd: "asdfg", ef: "zxcvb"}

You can replace the above looping logic with reduce or something else as you prefer.

This approach has the advantage that it takes advantage of the built-in parser, so we don't end up making assumptions about the syntax of XML. For instance, the regexp suggested in another answer would fail if the attributes had spaces before or after the equal sign. It would fail if the values contained Unicode characters. It would fail in odd ways if the XML was malformed. And so on.

Upvotes: 1

Scott Marcus
Scott Marcus

Reputation: 65815

First, your string is not valid (double quotes within double quotes). You'd either need to escape the inner quotes with \" or just replace the inner quotes with single quotes.

But, assuming that your data was always going to be in the format you show, this simple code will extract the data the way you want:

var data = "<First key='ab' value='qwerty'/><First key='cd' value='asdfg'/><First key='ef' value='zxcvb'/>";
data = data.replace(/<First /g, " ").replace(/\/>/g, "").replace(/key=/g, "").replace(/value=/g, "").trim();

var ary = data.split(" ");

var iteration = "";
var result = "";
for(var i = 0; i < ary.length; i+=2){
  
  iteration = ary[i].replace(/'/g, "") + ":" + ary[i+1].replace(/'/g, "\"");
  alert(iteration); 
  result += " " + iteration;
}

alert("Final result: " + result);

Upvotes: 0

IgrDi
IgrDi

Reputation: 655

Please, make your question more clear(What result data type would you like to get?), or try these functions:

var string = '<First key="ab" value="qwerty"/><First key="cd" value="asdfg"/><First key="ef" value="zxcvb"/>'

var ParseMyString1 = function(str){
var arr = str.split(/[</>]+/); //" 
//console.log(arr);
var result = [];

for (var i =0; i<arr.length; i++) {
    var subStr=arr[i];
    if (subStr.length!==0) {
        var subArr = subStr.split(/[\s"=]+/);    //" 
        //console.log(subArr);
        var currObj = {};            
        var currKey = "";
        var currVal = "";
        for (var j =0; j<arr.length; j++) {
            if (subArr[j]=="key"){
                currKey = subArr[++j];                                                            
            }else if (subArr[j]=="value"){
                currVal = subArr[++j];                                                            
            }
        };
        currObj[currKey] = currVal;
        result.push(currObj);
    };
};
console.log("ParseMyString1:");
console.log(result);
};

var ParseMyString2 = function(str){
var arr = str.split(/[</>]+/); //" 
//console.log(arr);
var resultObj = {};
for (var i =0; i<arr.length; i++) {
    var subStr=arr[i];
    if (subStr.length!==0) {
        var subArr = subStr.split(/[\s"=]+/);    //" 
        //console.log(subArr);

        var currKey = "";
        var currVal = "";
        for (var j =0; j<arr.length; j++) {
            if (subArr[j]=="key"){
                currKey = subArr[++j];                                                            
            }else if (subArr[j]=="value"){
                currVal = subArr[++j];                                                            
            }
        };
        resultObj[currKey] = currVal;

    };
};
console.log("ParseMyString2:");
console.log(resultObj);
};

$(document).ready(function(){
  ParseMyString1(string);
  ParseMyString2(string);
});

These functions return results as below (array of objects):

ParseMyString1:
[{ab:"qwerty"},{cd:"asdfg"},{ef:"zxcvb"}]
ParseMyString2:
{ab:"qwerty",cd:"asdfg",ef:"zxcvb"}

Upvotes: 0

Andy
Andy

Reputation: 63550

It would be useful to see the code you've attempted, but here's a way you could achieve it:

Use a regex to pick out the relevant parts of the string.

var regex = /key="([a-zA-Z]+)" value="([0-9a-zA-Z\-\.]+)"/;

Function to remove empty elements.

var notEmpty = function (el) { return el !== ''; };

split the string into an array on the carriage return and use reduce to build the new object by applying the regex to each array element.

var out = str.split('\n').filter(notEmpty).reduce(function(p, c) {
  var match = c.match(regex);
  p[match[1]] = match[2];
  return p;
}, {});

OUTPUT

{
  "ab": "qwerty",
  "cd": "asdfg",
  "ef": "zxcvb"
}

DEMO

Upvotes: 3

Related Questions