3

How do I get an array like this

[
    0: [ "first", "value", "1" ],
    1: [ "second", "value", "2" ],
    2: [ "third", "value", "3" ]
]

or even better

[ "first", "value", "1", "second", "value", "2", "third", "value", "3" ]

from the string

"first.value[1].second.value[2].third.value[3]"

relying on a single RegEx.exec() run?

I tried this:

regex = /\.*([\w]+)\.([\w]+)\[([\d]*)\]/g;
var str = "first.value[1].second.value[2].third.value[3]";
result = regex.exec(str);

but I can not get the sub-capturing-groups (like in the first example).

PS - I would like to get the regular expressions for both type of results (flat array or nested arrays)

Kamafeather
  • 8,663
  • 14
  • 69
  • 99
  • 1
    Use a loop and build the array dynamically. Something like `while ((m=regex.exec(str)) !== null) { arr.push(m[1], m[2], m[3]); ....};` See [this demo](https://jsfiddle.net/pny5qwfo/) yielding `["first", "value", "1", "second", "value", "2", "third", "value", "3"]` – Wiktor Stribiżew Feb 18 '16 at 12:39
  • I know I can do it manually. But I am curious how to do the same with a single regular expression. – Kamafeather Feb 18 '16 at 12:40
  • Could you clarify the *with a single regular expression* part? A regex expression cannot create, fill out arrays. There are specific language means for that. A regex expression can just match (or not match) some text. – Wiktor Stribiżew Feb 18 '16 at 12:44
  • I didn't want to use additional iteration structures and just rely on the regex magic! Or, at lease, I wanted to know if it is possible. But either you and Federico Piazza (in the comment to his answer) answered my doubt. Regex is not **so magic** then! – Kamafeather Feb 18 '16 at 14:04
  • 1
    It depends on the language. In Python, there are really cool methods in re and regex modules. It is just JS that is not so magical with regexps and its regexp methods are rather misleading. – Wiktor Stribiżew Feb 18 '16 at 14:28

5 Answers5

3

If the result from the edit, is what you're after

[ "first", "value", "1", "second", "value", "2", "third", "value", "3" ]

Then you can use a very simple regex.

/(\w+)/g

The cleanest way to achieve the first effect would require some array manipulation, as Regex cannot return nested structures.

You can use the above regex (/(\w+)/g) to get a matched array, and run it through the following:

var finalArr= [];

for (var i= 1, j= 0; i < matched.length; i += 3) {
  finalArr[j] = match.slice(i, 3);
  j++;
}
GMchris
  • 5,439
  • 4
  • 22
  • 40
3

I'd use split:

var str = "first.value[1].second.value[2].third.value[3]";
var res = str.split(/\]\.?|\[|\./)
Toto
  • 89,455
  • 62
  • 89
  • 125
2

Following your pattern idea, you can use a regex like this:

(.*?)\.(.*?)\[(\d+)\]\.?

Working demo

Match information

MATCH 1
1.  [0-5]   `first`
2.  [6-11]  `value`
3.  [12-13] `1`
MATCH 2
1.  [15-21] `second`
2.  [22-27] `value`
3.  [28-29] `2`
MATCH 3
1.  [31-36] `third`
2.  [37-42] `value`
3.  [43-44] `3`
Federico Piazza
  • 30,085
  • 15
  • 87
  • 123
  • I could achieve the same on _regex101.com_, but executing that on Javascript (that is where I need it to work), with _RegExp.prototype.exec()_, does not return that multi-level array. – Kamafeather Feb 18 '16 at 12:51
  • 2
    @Kamafeather I focused on your statement `or (even better)`. You cannot generate multi level arrays with regex. Regex is just a pattern matcher, if you need logic you have to add code in it – Federico Piazza Feb 18 '16 at 12:59
1

string.match(/(\w+)/g) The match method on string can produce an array you are looking for. Just extract the words with \w:

var regex = /(\w+)/g;
var str = "first.value[1].second.value[2].third.value[3]";

var arr = str.match(regex)


document.querySelector('pre').innerHTML = JSON.stringify(arr, 0, 4);
<pre></pre>
Jai
  • 74,255
  • 12
  • 74
  • 103
0

You can try in 2 steps, split using the ]. and then next step split using the .

var str = "first.value[1].second.value[2].third.value[3]";
var tempArr  = (str+'.').replace(/\[/g,'.').split('].');
var finalArr = tempArr.map(function(v){return v.split('.');});

//result: [["first", "value", "1"], ["second", "value", "2"], ["third", "value", "3"], [""]]
joyBlanks
  • 6,419
  • 1
  • 22
  • 47