drupie
drupie

Reputation: 11

Regex match last group of characters in brackets using Javascript

I find regex to be a pain. If I don't find an example that does exactly what I'm looking for I'm lost. I hope someone can give me a hand.

I have a string like this:

some text to be displayed (info) (more info)

I want to use regex to get the second set of brackets and the text inside. Or the last set that shows up. Like for this example I want to grab:

(more info)

So far I've found this:

\((?:[^()])*\)

But that gives me the first set, and I can't figure out how to get the second.

UPDATE Can I get the last set of brackets to be selected only when there is more than 1 set of brackets?

some text (info) (more info)

Should return:

(more info)

But if the it's this:

some text (info)

It wouldn't pick up anything

Upvotes: 0

Views: 262

Answers (2)

user557597
user557597

Reputation:

This gets the last set of braces in the string.
\([^()]*\)(?!.*?\([^()]*\)) for single line
\([^()]*\)(?![\S\s]*?\([^()]*\)) for multi-line

Expanded:

 \(              # Last '(..)'
 [^()]* 
 \)
 (?!             # Not '(..)' downstream
      .*? 
      \(
      [^()]* 
      \)
 )

UPDATE Can I get the last set of brackets to be selected only when there is more than 1 set of brackets?

Yes. Results in capture group 1.
\([^()]*\).*?(\([^()]*\))(?!.*?\([^()]*\))

Expanded:

 \(                            # Previous '(..)'
 [^()]* 
 \)
 .*? 
 (                             # (1 start), Last '(..)'
      \(                          
      [^()]* 
      \)
 )                             # (1 end)
 (?!                           # Not '(..)' downstream

      .*? 
      \(
      [^()]* 
      \)
 )

Upvotes: 0

user663031
user663031

Reputation:

Unless there's some compelling reason to use a regexp, you could also split, as follows:

function last_paren_item(str) {
    var pieces = str.split(/(\(.*?\))/);
                             ^-----^        PARENTHESIZED TEXT
                            ^-------^       KEEP SPLITTERS IN RESULT
    return pieces[pieces.length-2];
}

This takes advantage of the feature of split where the splitters are included in the result if included in parentheses (capturing group) in the regexp. The last parenthesized piece will always be the next to last element of the group.

> var str = "some text to be displayed (info) (more info)";
> var pieces = str.split(/(\(.*?\))/)
< ["some text to be displayed ", "(info)", " ", "(more info)", ""]
> pieces[pieces.length-2]
< "(more info)"

You might prefer this as more readable than regexp's like \([^()]*\)(?!.*?\([^()]*\)).

Upvotes: 0

Related Questions