3

I was trying to use a regular expression to match the inner text between two characters, but I am getting the wrong text

I tried putting [A-z]* instead of .* for matching only the inner text and it worked. But I need to match non-letter characters too.

/\[?(,? ?\[(\[(.+)-(.+)\])\])\]?/g

This is my regular expression and i want to match the characters between the square brackets:

[[[hello-hello]],[[hi-hi]]]

The bold characters are the one matched.

I'd expect to match [[[hello-hello]],[[hi-hi]]] in match 1 and [[[hello-hello]],[[hi-hi]]] in match two.

Emma
  • 27,428
  • 11
  • 44
  • 69
Pato05
  • 326
  • 1
  • 14

5 Answers5

3

If everything in between the [] would be desired, then we might simplify our expression to maybe:

(?:\[+)(.+?)(?:\]+)

Here, we capture our likely desired substring in this capturing group:

(.+?)

Then, we add two boundaries on its left and right sides using two non-capturing groups:

(?:\[+)
(?:\]+)

Demo

const regex = /(?:\[+)(.+?)(?:\]+)/g;
const str = `[[[hello-hello]]
[[hi-hi]]]
[[hi hi]]]`;
const subst = `$1`;

// The substituted value will be contained in the result variable
const result = str.replace(regex, subst);

console.log('Substitution result: ', result);

enter image description here

RegEx

If this expression wasn't desired, it can be modified/changed in regex101.com.

RegEx Circuit

jex.im visualizes regular expressions:

enter image description here

Emma
  • 27,428
  • 11
  • 44
  • 69
2

I'd use something like this:

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

This will match a [ character, if not followed by a [ character. It will then match any amount of non ] characters capturing them in group 1. Followed by matching a ] character.

const text = "[[[hello-hello]],[[hi-hi]]]";
const regex = /\[(?!\[)([^\]]*)\]/g;
var match;

while (match = regex.exec(text)) {
  console.log(match);
}

Alternatively you can leave out the capturing group and drop the first and last character of every match.

const text = "[[[hello-hello]],[[hi-hi]]]";
const regex = /\[(?!\[)[^\]]*\]/g;

console.log(
  text.match(regex)
      .map(match => match.slice(1, -1))
);
3limin4t0r
  • 19,353
  • 2
  • 31
  • 52
1

Here is the regex I came up with:

\[+([a-z- A-Z]+)\]+

Demo

Emma
  • 27,428
  • 11
  • 44
  • 69
Nicole M
  • 222
  • 2
  • 11
1

You could use 1 capturing group to capture your values.

The values before and after the hyphen could be matches using a negated character class \[([^][\n-]+ matching not an opening or closing bracket, a hyphen or a newline.

In your pattern you use a dot which will match any character except a newline so the negated character class contains a newline to prevent crossing lines.

\[([^\][\n-]+-[^\][\n-]+)]

Explanation

  • \[ Match [
  • ( Start capturing group
    • [^\][\n-]+ Negated character class, match 1+ times not ], [, - or a newline
    • - Match -
    • [^\][\n-]+ Match 1+ times not ], [, - or a newline
  • ) Close capturing group
  • ] Match ] char

Regex demo

const regex = /\[([^\][\n-]+-[^\][\n-]+)]/g;
const str = `[[[hello-hello]],[[hi-hi]]]`;
let m;

while ((m = regex.exec(str)) !== null) {
  if (m.index === regex.lastIndex) {
    regex.lastIndex++;
  }
  console.log(m[1]);
}
The fourth bird
  • 154,723
  • 16
  • 55
  • 70
0

RegEx

(?<=\[)([a-z- A-Z]+)(?=\])

(?<=\\[): Start with a bracket, but does not contain a bracket.

(?=\\]): End with a bracket, but does not contain a bracket.

Detailed explanations can be found in this link.

Community
  • 1
  • 1