Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to add access property and wrap the arguments with curly brackets with regex in js?

I have an array of strings. Each string might contain function calls.

I made this regular expression to match the word between $ctrl. and (, as long as it is immediately after $ctrl. and it will also match the parameters inside the parentheses if they exist.

/(\$ctrl\.)(\w+)(\(([^)]+)\))?/g;

Once there is a match then I add emit before the function call ($ctrl.foo() to $ctrl.foo.emit()), and if there are brackets then I wrap them with curly brackets: $ctrl.foo(account, user) to $ctrl.foo.emit({ account, user })).

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

The problem is this regex doesn’t work for some cases.

const inputs = [
  '$ctrl.foo(account)',
  '$ctrl.foo(account, bla)',
  '$ctrl.foo(account, bla); $ctrl.some()',
  '$ctrl.foo(account, bla);$ctrl.some(you)',
  '$ctrl.foo.some(account, bla);$ctrl.fn.some(you)',
  '$ctrl.gog',
];

const regex = /(\$ctrl\.)(\w+)(\(([^)]+)\))?/g;

inputs.forEach((input) => {
  let output = input.replace(regex, '$1$2.emit({$4})');
  console.log(output);
});

The results:

$ctrl.foo.emit({account})
$ctrl.foo.emit({account, bla})
$ctrl.foo.emit({account, bla}); $ctrl.some.emit({})()
$ctrl.foo.emit({account, bla});$ctrl.some.emit({you})
$ctrl.foo.emit({}).some(account, bla);$ctrl.fn.emit({}).some(you)
$ctrl.gog.emit({})

The first and two results are excellent. The regex adds emit and wraps the arguments with {..}.

But the regex is not working if I don’t have arguments or if I have another access property before the function call: $ctrl.foo.bar() (should not match this case).

What is missing in my regex to get those results?

$ctrl.foo.emit({account})
$ctrl.foo.emit({account, bla})
$ctrl.foo.emit({account, bla}); $ctrl.some.emit()
$ctrl.foo.emit({account, bla});$ctrl.some.emit({you})
$ctrl.foo.some(account, bla);$ctrl.fn.some(you)
$ctrl.gog

>Solution :

Maybe this modified regexp works better for you?

const inputs = [
  '$ctrl.foo(account)',
  '$ctrl.foo(account, bla)',
  '$ctrl.foo(account, bla); $ctrl.some()',
  '$ctrl.foo(account, bla);$ctrl.some(you)',
  '$ctrl.foo.some(account, bla);$ctrl.fn.some(you)',
  '$ctrl.gog',
];

const regex = /(\$ctrl\.)(\w+)(\(([^)]*)\))/g;

inputs.forEach((input) => {
  let output = input.replace(regex, '$1$2.emit({$4})');
  console.log(output);
});

I changed two quantifies in the regexp:

  • [^)]+ to [^)]* this allows also zero-length matches
  • )?/g to )/g this makes the existence of the \( ... \)-group at the end of the pattern no longer optional but compulsory.
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading