0

I need to parse the following string:

"Apple-sweet#tangy@Bannana@Orange-citrusy@Pear-crispy#green/yellow"

Each item except for the first that starts with "@" is the key, "-" denotes the start of subitems for that key. "#" separates each subitem with that same key.

Into an object similar to this:

{
"Apple": ["sweet", "tangy"],
"Bannana":[],
"Orange": ["citrusy"],
"Pear": ["crispy", "green/yellow"]
}

What is the best way to parse this?

3
  • I'd recommend the use of a parser generator such as pegjs.majda.cz/online Commented Nov 5, 2013 at 16:19
  • @Zzirconium How can that parser generator be applied to this problem? Commented Nov 5, 2013 at 16:58
  • I added an answer with my thoughts. Commented Nov 5, 2013 at 17:50

4 Answers 4

5

You need to split the string by the guard symbols several times:

var str = 'Apple-sweet#tangy@Bannana@Orange-citrusy@Pear-crispy#green/yellow';
var result = {};

str.split('@').forEach(function(item){
  var split = item.split('-'); 
  result[split[0]] = split[1] && split[1].split('#') || [];
});

console.dir(result);

First you split by @ to get each item from the object as a separate array value. Then you split each of the items in that array by - to get the key and the values. After that you need to make sure the values exist and if they do, split them by # to get an array of them.

DEMO: http://jsbin.com/avuGagu/1/edit

Sign up to request clarification or add additional context in comments.

Comments

3

You may try this (Example Here)

var str = "Apple-sweet#tangy@Bannana@Orange#citrusy@Pear#crispy#green/yellow";
var arr = str.split('@'), i = 0, l= arr.length, obj = {} ;
for(; i< l; i++){
    var a = arr[i].split(/-|#/);
    obj[a[0]] = a.splice(1);
}
console.log(obj);

Also, you can use (to make your keys lowercase, so you can use apple instead of Apple)

obj[a[0].toLowerCase()] = a.splice(1);

Example Here.

Comments

1

You just need a lot of string manipulation functions

var inputString = "Apple-sweet#tangy@Bannana@Orange-citrusy@Pear-crispy#green/yellow";
var keyValues = inputString.split("@");
var obj = {};

for (var i = 0; i < keyValues.length; ++i) {
    var index = keyValues[i].indexOf("-");
    if (index == -1) {
        obj[keyValues[i]] = [];
    } else {
        var key = keyValues[i].substring(0, index);
        var values = keyValues[i].substring(index + 1).split("#");
        obj[key] = values;
    }
}

FIDDLE

Comments

0

Just for fun, I tried to implement your "grammar" within PEG.js

Go there http://pegjs.majda.cz/online and paste the following grammar on the grammar part (1).

start
  = fruits

fruits
  = ft:fruit "@" fts:fruits  {fts[ft[0]] = ft[1]; return fts;}
  / ft:fruit {var fruits = {}; fruits[ft[0]] = ft[1]; return fruits;}

fruit
  = name:word "-" flavs:flavors {var ft = []; ft.push(name); ft.push(flavs); return ft;}
  / name:word {var ft = []; ft.push(name); ft.push([]); return ft;}

flavors
  = flavor:word "#" flavs:flavors {flavs.unshift(flavor); return flavs;}
  / flavor:word { var tab = []; tab.push(flavor); return tab;}

word
  = value:[a-zA-Z/]+ {return value.join("");}

Then put the sentence in the input section (2)

Apple-sweet#tangy@Bannana@Orange-citrusy@Pear-crispy#green/yellow

And here comes the result :

{
   "Pear": [
      "crispy",
      "green/yellow"
   ],
   "Orange": [
      "citrusy"
   ],
   "Bannana": [],
   "Apple": [
      "sweet",
      "tangy"
   ]
}

Then embed the resulting javascript parser into a file you won't have to bother about the lexical/syntaxic analysis job. Better maintenability to come only working at semantic level IMHO :)

Quite powerful API, although in this particular case it is a bit overkill ;)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.