james
james

Reputation: 4049

Regex to match content in last set of brackets, regardless of how many empty or filled brackets there are

Really struggling with this... trying to write a regex that pulls out the content in the last set of brackets even if there is no content (blank string). If it's helpful, the brackets will not nest inside one another.

Examples:

[][] => ""
[][a] => "a"
[a][] => ""
"a" => null
[][a][c][d][b] => "b"
ad[a][c][d] => "d"
[a][ra]dds[c] => "c"

Upvotes: 0

Views: 798

Answers (3)

timolawl
timolawl

Reputation: 5564

This solves your problem in one go without having to recheck the string:

var re = /.*\[([^\]]*)\]/;

The reason why this works is because the .* is greedy and will select everything up until the last instance of [ (anything but "]") ], with this last instance being the match. Thus, match 1 will have your expected result.

Here's the railroad diagram:

enter image description here

Here's the Regex101.

And here is a Stack Snippet of the test strings and match strings:

var testStrings = ['[][]', '[][a]', '[a][]', 'a', '[][a][c][d][b]', 'ad[a][c][d]', '[a][ra]dds[c]', '[a][ra]dasdf[c]asdf', '[][][]asdf', '[][]asdf][]', '[][a][asdfas][awef]asdf][]'];

var re = /.*\[([^\]]*)\]/;

testStrings.forEach(function(str) {
    var res = str.match(re) && str.match(re)[1]; /* re.exec(str) instead of str.match(re) also works */
    document.querySelector('.matchString').insertAdjacentHTML('beforeend', `<div>Match String: <span class='results'>${res}</span></div>`);

  document.querySelector('.testString').insertAdjacentHTML('beforeend', `<div>Test String: <span class='results'>${str}</span></div>`);
});
.testString {
  width: 50%;
  height: auto;
  float: left;
}

.matchString {
  width: 50%;
  height: auto;
  float: right;
}

.results {
  font-weight: bold;
  
}
<div class='testString'></div>
<div class='matchString'></div>

Upvotes: 0

user663031
user663031

Reputation:

var re = /\[([^[]*)\]$/;

This is similar to @Laurel's solution, but uses $ to find the last set of brackets directly, and allows it to be empty.

Upvotes: 0

Laurel
Laurel

Reputation: 6173

Why not go with something simple:

var re = /\[([^\]]+)\]/gim;

Looking back on it, it looks like a jumble of brackets. But it just finds two brackets and captures the character(s) inside them.

To find the last match, you just iterate through the array of matches.

If there is no match, but you still want to know if there are any empty brackets, you can JS's built in functions for strings. (I think it's indexOf("[]")). That will be faster than doing a regex.

Simple!

Upvotes: 1

Related Questions