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 })
).
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
CodePudding user response:
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.