How to extract body of this callback-ish style function using regex? - javascript

I'm trying to extract body of this function using JavaScript
J_Script(void, someName, (const char *str), {
function howdy() {
console.log("What's up");
}
howdy();
});
I have attempted the following regex,
(J_Script\s?)([^\.])([\w|,|\s|-|_|\$]*)(.+?\{)([^\.][\s|\S]*(?=\}))
It capture most of it but fails to detect end of the function thus corrputing the end result.
The end result need to looks like this,
function howdy() {
console.log("What's up");
}
howdy();
Yes, I know Regex maybe be not perfect for this but I don't have time to create an AST and I'm looking to do some pre-processing using Javascript.
Worth noting that the function will always ends with }); not })

Assuming your function has the substring }); starting at character 0 at the start of the function closing line (i.e. is flush to the left), you can use
(J_Script\s?)([^\.])([\w|,|\s|-|_|\$]*)(.+?\{)([^\.][\s|\S]*?(?=(^\}\);)))
With the multiline flag
The only modifications from your original are:
(J_Script\s?)([^\.])([\w|,|\s|-|_|\$]*)(.+?\{)([^\.][\s|\S]*?(?=^\}\);))
// ^ ^
// | |
// non-greedy beginning of line
If your functions have a fixed offset indentation, you can exploit that just the same, using /^ {x}/ where x is a digit representing whatever indentation count you have.
This also handles nested }); or whatever else might be in the function, so long as it's indented correctly.
If you want to capture the closing });, add a capture group to the above pattern:
(J_Script\s?)([^\.])([\w|,|\s|-|_|\$]*)(.+?\{)([^\.][\s|\S]*?(?=(^\}\);)))

Try changing the lookahead to find the }); that you always expect at the end:
(J_Script\s?)([^\.])([\w|,|\s|-|_|\$]*)(.+?\{)([^\.][\s|\S]*(?=(\}\);)))
Testbed: https://regex101.com/r/qdsB1w/1/

Related

javascript regex look behind to replace a character

I have a long strings of code that look something like
hs2^Ȁ_^HELLO_x_fs2^Ȁ_^WORLD_x_gn3^Ȁ_^HOME_x_gs3^Ȁ…
I need to do a replace. A hex character is used repeatedly Ȁ and there’s always a ^ in front of it. I need to change the number that appears before each ^Ȁ Reduce those numbers by 1. So the final result will be…
hs1^Ȁ_^HELLO_x_fs1^Ȁ_^WORLD_x_gn2^Ȁ_^HOME_x_gs2^Ȁ…
I’m really only dealing with two numbers here, 2 or 3, so the code would read something like this…
If (any number directly before ^Ȁ ==2) change it to 1
else if (any number directly before ^Ȁ ==3) change it to 2
I’ve heard of something called a “lookback” or “look behind” is that what’s needed here?
You can use replace with a callback function, which will be used to replace each occurrence using your own logic:
var str = "hs2^Ȁ_^HELLO_x_fs2^Ȁ_^WORLD_x_gn3^Ȁ_^HOME_x_gs3^Ȁ";
var res = str.replace(/\d(?=\^Ȁ)/g, num => --num);
console.log(res);
In the regex above, you'll notice this: (?=...). It's a positive lookahead, as suggested by #revo. It allows you to match ^Ȁ, but avoid passing it to your callback function. Only the digit (\d) will be passed, and thus, replaced.

javascript : problem with regular expression

I'm trying to validate the value of an input text field with the following code:
function onBlurTexto(value) {
var regexNIT = "([a-zA-z]|[0-9]|[&#,#.ÑñáéíóúÁÉÍÓÚ\|\s])";
regexCompilado = new RegExp(regexNIT);
if (!(regexCompilado.test(value))) {
alert("Wrong character in text :(");
return false;
} else {
return true;
}
}
But when i enter this text:
!65a
the function returns true (as you can see, the "!" character does not exist in the regular expression)
I'm not an expert in regular expressions, so i think i am missing something in the building of this reg.exp.
How can i put this regular expression to work?
Thanks in advance.
EDIT
i am so sorry ... i should remove the references to the variable "regexpValidar" before posting the issue. I modified the sample. Thanks #TecBrat
You should provide the start (^) and end ($) flags to your regex. Now you are matching 65a since you have alternate sets.
This should work /^([a-zA-z]|[0-9]|[&#,#.ÑñáéíóúÁÉÍÓÚ\|\s])+$/g
Demo: https://regex101.com/r/zo2MpN/3
RegExp.test looks for a match in the string, it doesn't verify that the whole string matches the regex. In order to do the latter, you need to add start and end anchors to your regex (i.e. '^' at the start and '$' at the end, so you have "^your regex here$").
I also just noticed that your regex is currently matching only one character. You probably want to add a '+' after the parens so that it matches one or more:
"^([a-zA-z]|[0-9]|[&#,#.ÑñáéíóúÁÉÍÓÚ\|\s])+$"
This is wrong. the variable you use doesn't has anything. Try this instead.
var regexCompilado = new RegExp(regexNIT);

Return inline comment to a new line

I am trying to parse a code block line-by line. Is there a way to grab in-line comments and return it to the next line? I would imagine using regex, but I am having trouble coming up with the expression.
Example:
if(foo) { //Executes bar function
bar();
}
will be
if(foo) {
//Executes bar function
bar();
}
Using JavaScript, could do something like turn all your code into a string and /(\/\/.+$)/g to capture inline comments and then use replace like:
stringVar.replace(/(\/\/.+$)/, '\n\t $1 \n').
If you have a text editor or IDE with regex support, you could use the above .replace pattern for the find and replace options respectively.
To match all single line - comments that are not in an otherwise empty line, you could use following regex:
/^.*\S+.*(\/\/.*$)/mg
https://regex101.com/r/fU5lO4/1
example
console.log("hello"); // this comment will be matched
// this comment won't be matched
// this comment won't be matched
You could replace the found comment with a newline + itself. (And maybe add some whitespaces?)
example
yourText.replace(/^(.*\S+.*)(\/\/.*$)/mg, '$1\n $2' );

A regular expression which excludes comments lines starting with "//" in JavaScript

I need to find all lines with string "new qx.ui.form.Button" WHICH EXCLUDE lines starting with comments "//".
Example
line 1:" //btn = new qx.ui.form.Button(plugin.menuName, plugin.menuIcon).set({"
line 2:" btn = new qx.ui.form.Button(plugin.menuName, plugin.menuIcon).set({"
Pattern should catch only "line 2"!
Be aware about leading spaces.
Finally I have to FIND and REPLACE "new qx.ui.form.Button" in all UNCOMMENTED code lines with "this.__getButton".
I tried.
/new.*Button/g
/[^\/]new.*Button/g
and many others without success.
In JavaScript this is a bit icky:
^\s*(?=\S)(?!//)
excludes a comment at the start of a line. So far, so standard. But you cannot look backwards for this pattern because JS doesn't support arbitrary-length lookbehind, so you have to match and replace more than needed:
^(\s*)(?=\S)(?!//)(.*)(new qx\.ui\.form\.Button)
Replace that by
$1$2this.__getButton
Quick PowerShell test:
PS Home:\> $line1 -replace '^(\s*)(?=\S)(?!//)(.*)(new qx\.ui\.form\.Button)','$1$2this.__getButton'
//btn = new qx.ui.form.Button(plugin.menuName, plugin.menuIcon).set({
PS Home:\> $line2 -replace '^(\s*)(?=\S)(?!//)(.*)(new qx\.ui\.form\.Button)','$1$2this.__getButton'
btn = this.__getButton(plugin.menuName, plugin.menuIcon).set({
That being said, why do you care about what's in the commented lines anyway? It's not as if they had any effect on the program.
Ah, if only JavaScript had lookbehinds... Then all you'd need is
/(?<!\/\/.*)new\s+qx\.ui\.form\.Button/g... Ah well.
This'll work just fine too:
.replace(/(.*)new\s(qx\.ui\.form\.Button)/g,function(_,m) {
// note that the second set of parentheses aren't needed
// they are there for readability, especially with the \s there.
if( m.indexOf("//") > -1) {
// line is commented, return as-is
// note that this allows comments in an arbitrary position
// to only allow comments at the start of the line (with optional spaces)
// use if(m.match(/^\s*\/\//))
return _;
}
else {
// uncommented! Perform replacement
return m+"this.__getButton";
}
});
Grep uses Regular Expressions, this will exclude all white space (if any) plus two // at the beginning of any line.
grep -v "^\s*//"

JavaScript: string.match regular expression help

I have a javascript function that looks element id with certain patterns. So I have the following script:
if (f.elements[i].id.match(/DataList\[-\d{3}|\d{3}\]\.MemberId/)) {
//do something
}
It should match elements with ids such as these:
DataList[-1].MemberId
DataList[-2].MemberId
And it does, however it also matches the following:
DataList[-1].FirstName
DataList[-2].FirstName
which I don't want.
Could any guru take a look at the regular expression above and point out what is going wrong?
Thanks,
Cullen
Try to anchor your regex at the beginning with a ^ and at the end with a $, group your digit match and allow 1-3 digits instead of just 3.
if (f.elements[i].id.match(/^DataList\[(-\d{1,3}|\d{1,3})\]\.MemberId$/)) {
//do something
}
The way you had it, it was matching anything containing "DataList[-123" or containing "123].MemberId".
A simpler overall regex that accomplishes the same thing is:
if (f.elements[i].id.match(/^DataList\[-?\d{1,3}\]\.MemberId$/)) {
//do something
}
The or is saying:
DataList\[-\d{3} OR \d{3}\]\.MemberId/
This regex matches correctly:
DataList\[-?\d{1,3}\]\.MemberId
My suggestion
if (f.elements[i].id.match(/DataList\[-[0-9]{1,3}\]\.MemberId/)) {
}
The {} determines how many #s you want to support so 1-3 would match upu to [999]

Categories