admin管理员组

文章数量:1336568

I'm trying to match the last occurrence of a pattern in a string.

I want to get the last word in the parenthesis in the following string:

(Don't match this) and not this (but this)

I've tried the following,

\s(\((.*?)\))(?!\))

But this matches both occurrences, not only the last one. Is it possible to just match the last one?

I'm trying to match the last occurrence of a pattern in a string.

I want to get the last word in the parenthesis in the following string:

(Don't match this) and not this (but this)

I've tried the following,

\s(\((.*?)\))(?!\))

But this matches both occurrences, not only the last one. Is it possible to just match the last one?

Share Improve this question edited May 7, 2015 at 7:49 ngrashia 9,9045 gold badges44 silver badges58 bronze badges asked May 7, 2015 at 7:46 dvlprdvlpr 1221 silver badge9 bronze badges 5
  • Match all of them with global flag on regex, then pick the last match from the match array? It's the simplest approach, without the need to touch on look-ahead and stuffs. – nhahtdh Commented May 7, 2015 at 7:49
  • check this regexr./3auvb – Afsar Commented May 7, 2015 at 7:51
  • it should return an array.. can you see that? – maioman Commented May 7, 2015 at 7:52
  • @zan: The regex works on the example in the question, but it returns 2 matches if you add the string (something) at the end. – nhahtdh Commented May 7, 2015 at 7:54
  • Check this: regex101./r/gT5lT5/2 – anishsane Commented May 7, 2015 at 7:56
Add a ment  | 

2 Answers 2

Reset to default 6

Match all strings in bracket /\(.*?\)/g and post process the result

You can just match all strings satisfying the pattern, and pick the last element from the resulting array. There is no need to e up with a plicated regex for this problem.

> "(Don't match this) and not this (but this)".match(/\(.*?\)/g).pop()
< "(but this)"

> "(Don't match this) and not this (but this) (more)".match(/\(.*?\)/g).pop()
< "(more)"

> "(Don't match this) and not this (but this) (more) the end".match(/\(.*?\)/g).pop()
< "(more)"

Don't want the () in the result? Just use slice(1, -1) to get rid of them, since the pattern fixes their positions:

> "(Don't match this) and not this (but this)".match(/\(.*?\)/g).pop().slice(1, -1)
< "but this"

> "(Don't match this) and not this (but this) (more) the end".match(/\(.*?\)/g).pop().slice(1, -1)
< "more"

Using .* to search for the last instance of the pattern

This is an alternate solution with simple regex. We make use of the greedy property of .* to search for the furthest instance matching pattern \((.*?)\), where the result is captured into capturing group 1:

/^.*\((.*?)\)/

Note that no global flag is used here. When the regex is non-global (find first match only), match function returns the text captured by capturing group, along with the main match.

> "(Don't match this) and not this (but this)".match(/^.*\((.*?)\)/)[1]
< "but this"

> "(Don't match this) and not this (but this) (more) the end".match(/^.*\((.*?)\)/)[1]
< "more"

The ^ is an optimization to prevent the engine from "bumping along" to search at subsequent indices when the pattern .*\((.*?)\) fails to match from index 0.

You can use non capturing parenthesis to consume previous matches:

var string="(Don't match this) and not this (but this) definitely not this";
var last_match=string.match(/(?:.*\()([^\)]*)(?:\)[^\(]*)/)[1];

Tested using web developer console:

< var string="(Don't match this) and not this (but this) definitely not this";
< string.match(/(?:.*\()([^\)]*)(?:\)[^\(]*)/)[1]
>"but this"

Here is the link for testing: https://regex101./r/gT5lT5/2
If you want that the enclosing parenthesis to be part of the match, check https://regex101./r/gT5lT5/1

本文标签: javascriptFind the last occurrence of a patternStack Overflow