0

I've found a lot of regex examples for matching content within nested brackets, but what I want to do is match:

  • a function with a particular name
  • match ALL content inside the curly braces (including any NESTED curly braces)

For example:

function someFunc() {
  const a = 6;

  if (a === 7) {
    while (true) {
      break;
    }
  }
}

This should find function someFunc+ignore anything up to first curly+then match all contents within the curly braces, including any nested braces.

I'm a noob at regex so I can't show you what I've done, I've been looking at Regex to get string between curly braces "{I want what's between the curly braces}" but none of them are suitable. Thanks!

PS expected output is a capture group of all contents within a function (which I can then replace).

Dominic
  • 62,658
  • 20
  • 139
  • 163
  • 2
    Counting brackets is afaik too much to ask for regular expressions, unless you use exotic features that extend them past regular grammar's possibilities (which likely aren't there in javascript) – ASDFGerte Mar 12 '18 at 15:57
  • It wasn't very clear for me what is the expected result for this input - could you clarify it? – arieljannai Mar 12 '18 at 16:01
  • Something like this is better suited to using a parser. There are plenty of good parser engines out, eg. `https://pegjs.org/` In fact seen as it's Javascript your parsing, you could even use Babel, it has all the AST worked out for you. – Keith Mar 12 '18 at 16:03
  • JS engine doesn't support recursions. So you can't do it in JS. – revo Mar 12 '18 at 16:06
  • Regular expressions are only useful with [regular languages](https://en.wikipedia.org/wiki/Regular_language). JavaScript is [not a regular language](https://stackoverflow.com/questions/25247030/is-javascript-ecmascript-a-regular-language) –  Mar 12 '18 at 16:08
  • Thanks guys, I'll write it in plain old JS then! (or use a parser) – Dominic Mar 12 '18 at 16:10
  • Would it be useful to take an oposite approach and REMOVE all un needed characters? In your description it looks like you just dont need `()` followed by a `{` at your function declaration... – Francis Leigh Mar 12 '18 at 16:12
  • I would actually like to replace all the contents, so it should be `function someFunc() {}`. I will use some simple JS for this as it doesn't have to be resilient to strange function contents like strings with unmatched braces etc – Dominic Mar 12 '18 at 16:15
  • If you have properly closed braces, you are lucky (even if it is difficult) - parsers work better than regexes. If there is an error in the code (improperly matched braces, even missing / extra braces), you may be out of luck. Please note that the word "function" may appear as a string inside the function (comment or fragment of keyword). Even smart parsers are sometimes bad at this, as far as I encountered. – virolino Feb 12 '19 at 08:17

2 Answers2

1

Maybe this helps?

functionName\(.*{(.|\n)*}\n{2,}

this will search for a function called functionName followed by an open parenthesis and will get everything until it finds a closing curly bracket followed by two or more line breaks.

Here is a Regex101 to test it.

https://regex101.com/r/BadtRu/3

R. Schifini
  • 9,085
  • 2
  • 26
  • 32
  • Thanks, there is only 1 line break after this function and I can't change that but good idea – Dominic Mar 12 '18 at 16:37
  • Are all functions followed by another? In that case add `function` at the end of the regexp (and remove `{2,}`) – R. Schifini Mar 12 '18 at 16:51
  • It is followed by another, but also inside there are three nested functions using the 'function' keyword – Dominic Mar 12 '18 at 17:13
0

I've made a very naive function for this (because that's all I need as I know what the contents of the function looks like):

function loader(content, functionName) {
  // Find function
  const indexOfFunc = content.indexOf(`function ${functionName}`);

  if (indexOfFunc < 0) {
    return content;
  }

  const openingBrace = content.indexOf('{', indexOfFunc);

  // WARNING: We are assuming all braces in the function are balanced.
  // This won't be the case if there are braces in strings or comments
  // which aren't!
  const startPos = openingBrace + 1;
  let endPos = startPos;
  let bracesToBalance = 1;

  while (true) {
    if (content[endPos] === '{') {
      bracesToBalance++;
    } else if (content[endPos] === '}') {
      bracesToBalance--;
      if (bracesToBalance === 0) break;
    }
    endPos++;
  }

  return content.slice(0, startPos) + content.slice(endPos);
};
Dominic
  • 62,658
  • 20
  • 139
  • 163