1

I have this string that I am trying to increment each word/property by adding a _# with the # being the incremented number on the left side of the {.

 str = 'View{Image{BackgroundImage: Image.png;Position: 0, 0;Width: 320;Height: 480;}Button{BackgroundImage: ButtonTop.png;Position: 61, 83;Width: 217;Height: 58;}Button_2{BackgroundImage: ButtonBottom.png;Position: 21, 303;Width: 217;Height: 58;}}'

In the past I have used this regex, but its not working and I cant figure out why.

var i = {};
str = str.replace(/(\S+):{/g, function (m, p1) {
            i[p1] = (i[p1] || 0) + 1;
            return p1 + "_" + i[p1].toString() + ":{";
        });

The desired out put is:

str = 'View_1{Image_1{BackgroundImage: Image.png;Position: 0, 0;Width: 320;Height: 480;}Button_1{BackgroundImage: ButtonTop.png;Position: 61, 83;Width: 217;Height: 58;}Button_2{BackgroundImage: ButtonBottom.png;Position: 21, 303;Width: 217;Height: 58;}}'
Rob
  • 11,185
  • 10
  • 36
  • 54

2 Answers2

1

According to your regex, it is looking for a colon : in front of a left curly bracket {, which isn't present in your string. Try changing the beginning of the string to:

str = 'View:{Image...';

Update: I'm not sure what is contained in the i variable - is it always an empty object? But if you continue to increment the number, this replace function might work better for you (demo):

str = str.replace(/([a-zA-Z]+_?)(\d+)?:{/g, function (m, n, d) {
  d = (parseInt(d,10) || 0) + 1; // add one
  if (!/_$/.test(n)) { n += '_'; } // add _ if name doesn't have it
  return n + d + ":{";
});
Mottie
  • 84,355
  • 30
  • 126
  • 241
1

A few small but crucial changes should get it working.

Firstly, I think there's a tiny mistake in your str. For example, you have Button_2 towards the end of str but I'm assuming you just want this to be Button and for your replace function to take care of the incrementing. Otherwise, the result would be Button_2_1... So I'm assuming you want str to be this:

str = 'View{Image{BackgroundImage: Image.png;Position: 0, 0;Width: 320;Height: 480;}Button{BackgroundImage: ButtonTop.png;Position: 61, 83;Width: 217;Height: 58;}Button{BackgroundImage: ButtonBottom.png;Position: 21, 303;Width: 217;Height: 58;}}'

If that's then right here's the corrected code (which I hope will work for you), with the explanation after:

var i = {};

str = str.replace(/(\w+){/g, function (m, p1) {
    i[p1] = (i[p1] || 0) + 1;
    return p1 + "_" + i[p1].toString() + ":{";
});

In the original code you had \S in the parentheses but this is too general, as it will capture even the opening curly brace {. In regexp, a capital \S means any character that is not a space. A lowercase \w will find alphanumeric characters so this is probably what you want to capture the word View, and Image, etc. So now any alphanumeric part of the string followed directly (no spaces) by an opening curly brace will be replaced with an underscore and a number, which increments with each instance of that item.

I wasn't sure if you actually want the colon : to appear after each number so I have left it in but if you actually don't want it just replace the return statement with return p1 + "_" + i[p1].toString() + "{";

Otherwise, if you're happy with above (colon included), this is the resulting string:

View_1:{Image_1:{BackgroundImage: Image.png;Position: 0, 0;Width: 320;Height: 480;}Button_1:{BackgroundImage: ButtonTop.png;Position: 61, 83;Width: 217;Height: 58;}Button_2:{BackgroundImage: ButtonBottom.png;Position: 21, 303;Width: 217;Height: 58;}}

Which I think is what you wanted. I've set up a fiddle so you can see the corrected code in action and have a play.

Hope this helps.

guypursey
  • 3,114
  • 3
  • 24
  • 42
  • this is very close, but you are incrementing each item by 1, where each item should increment on its own. For example View, Button, Label, Button would be View_1, Button_1, Label_1, Button_2. It does look like my primary problem is the missing semicolon though – Rob Jan 06 '13 at 22:04
  • Hi @Rob. I've updated my answer to reflect what you mention here. The `p1 +` in the return statement makes a lot more sense now that I know you want each item to increment on its own so that's back in and I've adjusted the regexp accordingly. – guypursey Jan 07 '13 at 11:24
  • @Rob PS. I wasn't sure what you meant about the semi-colon (colon?) but I've attempted to cover that in my answer. – guypursey Jan 07 '13 at 11:25