Return inline comment to a new line - javascript

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' );

Related

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

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/

Regex to match everything outside of a regex pattern

So I'd like to use javascript to replace all the words outside of HTML tags in a body of text. Check the explanation below.
I'd like to convert this:
<tag with-attr="something"></tag><tag>Text to match</tag><tag>Text to Match</tag>
...to this:
<tag with-attr="something"></tag><tag>Manipulated Text</tag><tag>Manipulated Text</tag>
Now, I have a regular expression that can match all the tags and its containing text:
\<[^>]*\>
But I'm not sure how to invert the expression, so to speak.
EDIT
Also, I'm looking to use the replace / match functions, not split, since I want to retain the tag information and spit the a working page back out with the new information.
using a paren-including split() RegExp and further array methods make "stream processing" fairly simple:
'<tag with-attr="something"></tag><tag>Text to match</tag>Text to Match<tag>'
.split(/(<[^>]+>)/).map(function(x,i){
if(!(i%2) && x){ x= escape(x); }
return x;
}).join("");
example output:
"<tag with-attr="something"></tag><tag>Text%20to%20match</tag>Text%20to%20Match<tag>"
the escape() is just to show that the textContent has indeed been altered...
i only vouch for input close to your example. deeply nested or invalid HTML might fool any RegExp, but i'm sure someone else will bring that up...
Something like this
/>([^<>]*\w)</
demo here : http://rubular.com/r/2QPLjOeMAu
Now you just need to replace the content like this :
var str = '<tag with-attr="something"></tag><tag>Text to match</tag><tag>Text to Match</tag>';
var res = str.replace(/>([^<>]*\w)</g, '>Manipulated text<');
console.log(res);

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*//"

How would I make a regular expression that would mean /some string/ either followed by a line break or not?

function(input){
return input.replace(/teststring/ig, "adifferentstring");
}
I want to replace "teststring" and "teststring\n" with "adifferentstring"
In regex, to match a specific character you can place it in brackets:
[\n]
To make the match "optional", you can follow it with a ?:
[\n]?
In your exact example, your full regex could be:
teststring[\n]?
So, your function would look like:
function replace(input) {
return input.replace(/teststring[\n]?/ig, "adifferentstring");
}
I'd suggest going with matching characters in brackets as this makes for easy expansion; consider, for instance, that you want to match Window's newlines (a carriage-return + a newline):
teststring[\r\n]?
Try
function(input){
return input.replace(/teststring\n?/ig, "adifferentstring");
}
Try .replace(/teststring[\n]?/ig,"adifferentstring");
It would be something like this:
var re = /teststring([\n]?)/ig;
So then your replace statement would look about like this:
return input.replace(re,"adifferentstring");
Here's a fiddle showing the regex works.
And then a fiddle showing the replace operation working.
Edit:
Actually, thinking about the problem a little further, if your regex does match a carriage return or new line character, that would need to get put back into the replacing string. The same regex I posted originally will work but you will need this replace statement instead (with the $1 denoting the first group in parantheses.
return input.replace(re,"adifferentstring$1");
fiddle

Regular expression to find all methods in a piece of code

I am trying to write a regular expression to match all the JavaScript method definitions in a constructor string.
//These two should match
this.myMethod_1 = function(test){ return "foo" }; //Standard
this.myMethod_2 = function(test, test2){ return "foo" }; //Spaces before
//All of these should not
//this.myMethod_3 = function(test){ return "foo" }; //Comment shouldn't match
/**
*this.myMethod_4 = function(test){ return "foo" }; //Block comment shouldn't match
*/
// this.myMethod_5 = function(test){ return "foo" }; //Comment them spaces shouldn't match
/*
* this.myMethod_6 = function(test){ return "foo" }; //Block comment + spaces shouldn't match
*/
this.closure = (function(){ alert("test") })(); //closures shouldn't match
The regular expression should match ['myMethod_1', 'myMethod_2']. The regular expression should not match ['myMethod_3', 'myMethod_5', 'myMethod_6', 'closure'].
Here's what I have so far, but I am having problems with the ones that appear in comments:
/(?<=this\.)\w*(?=\s*=\s*function\()/g
I've been using this cool site to test it.
How do I solve this?
This sounds complicated to do it correctly. You will need to create a parser for this, a simple regular expression will most likely not make it.
A very good starting point is Narcissus, which is a JavaScript parser written in ... JavaScript.
It is just 1000 lines of code. It should be possible to extract just the method-matching parts of it.
Add a ^\s* to the begining might help. It's not perfect, but it will work for your test cases.
One regular expression might be difficult to write and debug. Think about writing several regular expressions, one for each line that should either match to confirm or reject a piece of code.
For example,
/(?<=this.)\w*(?=\s*=\s*function()/g // Matches a simple constructor.
/^\/\// // If it matches then this line starts with a comment.
and so on.

Categories