5

This is an example of the string that's being worked with:

xxxxxx[xxxxxx][7][xxxxxx][9][xxxxxx]

I'm having a little trouble matching the second occurrence of a match, I want to return the 2nd square brackets with a number inside. I have some regex finding the first square backets with numbers in a string:

\[+[0-9]+\]

This returns [7], however I want to return [9].

I'm using Javascript's replace function, the following regex matches the second occurrence (the [9]) in regex testeing apps, however it isn't replaced correctly in the Javascript replace function:

(?:.*?(\[+[0-9]+\])){2}

My question is how do I use the above regex to replace the [9] in Javasctipt or is there another regex that matches the second occurrence of a number in square brackets.

Cheers!

3 Answers 3

3

If xxx is just any string, and not necessarily a number, then this might be what you want:

(\[[0-9]+\]\[.*?\])\[([0-9]+)\]

This looks for the second number in []. Replace it with $1[<replacement>]. Play with it on rubular.

Your regular expression fails to work as intended because groups followed by + only end up holding the last [xxx].

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

7 Comments

Why are you using {3} as a quantifier? This doesn't appear to be a "there will always be three tags before the one we want, and one after" situation, shouldn't you base the regex on the actual requirements stated by the asker? Personally, I would use /(\[\d+\](?:\[.*?\D.*?\])*)(\[\d+\])/\1[replacement]/
@Anon We don't know that xxx isn't a number. I assumed it was, but maybe I'm wrong.
I've added another regex which will replace the second [<number>].
@marcog: The asker mentioned he wanted "the second match", so I think we can presume that [xxx] doesn't match the same thing as [9]. Though it is unclear whether [xxx] can be things like [123], or whether it must have something that isn't a digit in it.
@Anon Do you agree with my new regex?
|
1

Try

result = subject.replace(/(\[\d\]\[[^\]]+\])\[\d\]/, "$1[replace]");

As a commented regex:

(       # capture the following in backref 1:
\[\d\]  # first occurrence of [digit]
\[      # [
 [^\]]+ # any sequence of characters except ]
\]      # ]
)       # end of capturing group
\[\d\]  # match the second occurence of [digit]

If the number of [xxx] groups between the first and second [digit] group is variable, then use

result = subject.replace(/(\[\d\](?:\[[^\]]+\])*?)\[\d\]/, "$1[replace]");

By surrounding the part that matches the [xxx] groups with (non-capturing) parentheses and the lazy quantifier *? I'm asking the regex engine to match as few of those groups as possible, but as many as necessary so the next group is a [digit] group.

Comments

0
console.log( "xxxxxx[xxxxxx][7][xxxxxx][9][xxxxxx]".replace(
/^(.*\[[0-9]+\].*)(\[[0-9]+\])(.*)$/, 
'$1[15]$3')); // replace with matches before ($1) and after ($3) your match ($2)

returns:

// xxxxxx[xxxxxx][7][xxxxxx][15][xxxxxx]

It will match where [n] is preceeded by 1 set of brackets with numbers inside.

1 Comment

Not sure if this is important, but this fails on [1][2][3] - replaces the last [3]. Maybe the OP should provide some tests...

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.