mmBs
mmBs

Reputation: 8559

Decomposing a string with parenthesis using regex

I have a problem with decomposing a string.

The problem:

I want to decompose string like this:

(01)12345678901234(11)060606(17)121212(21)1321asdfght(10)aaabbb

and return an object like this:

Object {
       identifier01: "12345678901234", 
       identifier11: "060606", 
       identifier17: "121212", 
       identifier21: "1321asdfght", 
       identifier10: "aaabbb" 
}

Rules:
identifier01 has always 14 numeric characters
identifier11 has always 6 numeric characters
identifier17 has always 6 numeric characters
identifier21 has always from 1 to 20 alphanumeric characters
identifier10 has always from 1 to 20 alphanumeric characters

The problem is the identifier21 and identifier10 do not have a fixed length of characters (they vary from 1 do 20 characters). What is more, only identifier01 is always at the beginning and rest of identifiers can have a different order, let's say:

(01)12345678901234(21)111122233344(10)abcdeed(11)050505(17)060606

or even a particular identifier could not exist at all:

(01)12345678901234(21)111122233344(17)060606

My approach:

parseStringToAnObject: function (value) {
           var regs = [
                ["(01) ", /\([^)]*01\)([0-9]{14})/],
                ["(10) ", /\([^)]*10\)([0-9a-zA-Z]{1,20})/],
                ["(11) ", /\([^)]*11\)([0-9]{6})/],
                ["(17) ", /\([^)]*17\)([0-9]{6})/],
                ["(21) ", /\([^)]*21\)([0-9a-zA-Z]{1,20})/]
            ];

            var tempObj = {};

            while (value.length > 0) {
                var ok = false;
                for (var i = 0; i < regs.length; i++) {
                    var match = value.match(regs[i][1]);
                    console.log(match);
                    if (match) {
                        ok = true;
                        switch (match[0].slice(0, 4)) {
                            case "(01)":
                                tempObj.identifier01 = match[1];
                                break;
                            case "(21)":
                                tempObj.identifier21 = match[1];
                                break;
                            case "(11)":
                                tempObj.identifier11 = match[1];
                                break;
                            case "(17)":
                                tempObj.identifier17 = match[1];
                                break;
                            case "(10)":
                                tempObj.identifier10 = match[1];
                                break;
                         }

                        value = value.slice(match[0].length);
                        break;
                    } else {
                        console.log("Regex error");
                    }
                }
                if (!ok) {
                    return false;
                }
            }
            console.log(tempObj);
            return tempObj;
 }

Results:

My function returns me a proper data but only when I do not type identifiers with variable amount of characters. When I type e.g.

(01)12345678901234(21)abder123(17)121212

or

(01)12345678901234(10)123aaaaabbbddd(21)qwerty

or

(01)12345678901234(17)060606(10)aabbcc121212(11)030303

it always returns me false.

Could you suggest a better and more refined approach, please?
Thanks for all answers and solutions in advance!

Upvotes: 2

Views: 108

Answers (2)

dave
dave

Reputation: 64657

I wouldn't even use regex:

var final = {}; 
var a = "(01)12345678901234(11)060606(17)121212(21)1321asdfght(10)aaabbb";
a.split("(").slice(1).sort().map(function(i) {
    var pieces = i.split(')'); 
    final["identifier" + pieces[0]] = pieces[1]; 
});
console.log(final);

//Object {identifier01: "12345678901234", identifier10: "aaabbb", identifier11: "060606", identifier17: "121212", identifier21: "1321asdfght"}

Upvotes: 1

Kenney
Kenney

Reputation: 9093

Here's how I'd do it:

var s = "(01)12345678901234(11)060606(17)121212(21)1321asdfght(10)aaabbb",
    r = {};

s.replace( /\((\d\d)\)([^()]+)/g, function(m,p,d){ r['identifier'+p]=d;return '';} );
 
console.log(r);

Upvotes: 1

Related Questions