RegEx change function name and parameter of string - javascript

I'm awful with RegEx to begin with. Anyway I tried my best and think I got pretty far, but I'm not exactly there yet...
What I have:
A javascript source file that I need to process in Node.js. Can look like that:
var str = "require(test < 123)\n\nrequire(test2 !== test)\n\nfunction(dontReplaceThisParam) {\n console.log(dontReplaceThisParam)\n}";
What I came up with:
console.log(str.replace(/\(\s*([^)].+?)\s*\)/g, 'Debug$&, \'error_1\''))
Theres a few problems:
I want that the string error gets inside the paranthesis so it acts as a second parameter.
All function calls, or I think even everything with paranthesis will be replaced. But only function calls to "require(xxx)" should be touched.
Also, the error codes should somehow increment if possible...
So a string like "require(test == 123)" should convert to "requireDebug(test == 123, 'error_N')" but only calls to "require"...
What currently gets outputted by my code:
requireDebug(test < 123), 'error_1'
requireDebug(test2 !== test), 'error_1'
functionDebug(dontReplaceThisParam), 'error_1' {
console.logDebug(dontReplaceThisParam), 'error_1'
}
What I need:
requireDebug(test < 123, 'error_1')
requireDebug(test2 !== test, 'error_2')
function(dontReplaceThisParam) {
console.log(dontReplaceThisParam)
}
I know I could just do things like that manually but we're talking here about a few hundred source files. I also know that doing such things is not a very good way, but the debugger inside the require function is not working so I need to make my own debug function with an error code to locate the error. Its pretty much all I can do at the moment...
Any help is greatly appreciated!

Start the regex with require, and since you need an incrementing counter, pass a function as the second arg to replace, so that you can increment and insert the counter for each match.
var str = "require(test < 123)\n\nrequire(test2 !== test)\n\nfunction(dontReplaceThisParam) {\n console.log(dontReplaceThisParam)\n}";
var counter = 0;
console.log(str.replace(/require\(\s*([^)].+?)\s*\)/g, (s, g2) =>
`requireDebug(${g2}, \'error_${++counter}\')`
));
Other than that, your code was unaltered.

Related

Why do I get undefined here?

function myFunc() {
var word = document.getElementById("Text1").value;
var num = parseInt(document.getElementById("Text2").value);
var numstr = num.split(",");
var wordstr = word.split("");
for (i = 0; i < word.length; i++) {
}
document.getElementById("myDiv").innerHTML += (wordstr[(numstr[i])-1]);
}
did I parseInt incorrectly? I've tried toString(), with ParseInt it doesn't do anything and without it I get 'undefined'
The parseInt() function parses a string and returns an integer.
You check your input with id "Text2" and show your HTML here to clearify the issue.
Without knowing more about your problem, it looks like you are misunderstanding how parseInt() works. Despite the misleading name, it will read your string character by character, attempting to create an integer. It will stop as soon as it finds a character that can't be part of an integer.
If you pass it "1,2,3,4" then it will read the 2 fine, but as a comma cannot be parsed as part of an integer, it will return the number 2. It doesn't make sense to call split on a number.
As others have said, you really need to give us more details for us to be able to help, but I suspect a large part of the problem is not understanding what some of these functions do.
Maybe you could explain what you're trying to achieve, then we can help you get there. Right now, your code isn't clear enough without extra information.

Replace markup in file without writing new file

I have HTML markup in a file. I intend picking out that markup, replacing the placeholders in it per the data set, and returning a merged string. I could simply use a server-side template (I did previously) but cannot afford it now as some client-side code requires same markup for front end stuff i.e code beyond public/. Presently, the server just hangs whenever it runs into the exec function and throws nor console.errors nothing.
The code looks like this
var availableFoodsString = "",
regexCb = function (dataSet, flag, indexPage) {
return function(match, $1, index) {
if (indexPage == undefined && dataSet["username"] != undefined) {
dataSet["username_search"] = dataSet["username"];
}
if (dataSet[$1] != undefined) return dataSet[$1];
else if (flag == "EMPTY") return "";
else if (flag == "MATCH") return match;
}
};
foodsModel.find({availableToday: true}, function(err, docs) {
if (err) throw err;
docs.forEach(function (doc) {
doc = doc.toObject();
doc.image = "/images/food/" + doc.name + ".jpg";
var template = /(<div class="food-menu">(\s*.*)*<\/div>)/gi.exec(fs.readFileSync("public/index.html").toString())[0]
availableFoodsString += template.replace(/\{\{(\w+)\}\}/gi, regexCb(doc))
});
});
In essence, I need availableFoodsString at the end of the day as an additional value to be rendered to another placeholder i.e render({available: availableFoodsString}).
The public/index.html is a normal HTML with this somewhere in between
{{name}}
{{price}}
add to cart
So, some jQuery code also needs this much coveted markup at some point after DOM is fully loaded, while doc from the model contain name and price filler variables.
The foodsModel.find() function is async, yes, but it is called inside the http.createServer function by the database opening connection callback so the variable is definitely loaded at that point.
I have seen some other solutions such as this and related questions but they all either involve imploring some external module from npm, or writing a new file from the matched markup, before replacing and merging into the desired variable. I know there has to be a way to achieve this without any of those.
The problem had to do with my regex. The second parenthesis was guilty of something called catastrophic backtracking. Which means the match was greedy in a way that put the interpreter through hell i.e. taking back more than needed instead of inversely giving back as needed. I knocked up a few spots on the regex and everything works seamlessly now.
The old code stayed the same, just the regex changed from this:
/(<div class="food-menu">(\s*.*)*<\/div>)/gi
to this:
/(<div class="food-menu">(\s+.*)+<\/div>)/g
For some reason, the previous regex appeared to match the file string seamlessly, first time I tested it, but was brutally unforgiving once I plugged it in real code.

How to make indexOf only match 'hi' as a match and not 'hirandomstuffhere'?

Basically I was playing around with an Steam bot for some time ago, and made it auto-reply when you said things in an array, I.E an 'hello-triggers' array, which would contain things like "hi", "hello" and such. I made so whenever it received an message, it would check for matches using indexOf() and everything worked fine, until I noticed it would notice 'hiasodkaso', or like, 'hidemyass' as an "hi" trigger.
So it would match anything that contained the word even if it was in the middle of a word.
How would I go about making indexOf only notice it if it's the exact word, and not something else in the same word?
I do not have the script that I use but I will make an example that is pretty much like it:
var hiTriggers = ['hi', 'hello', 'yo'];
// here goes the receiving message function and what not, then:
for(var i = 0; i < hiTriggers.length; i++) {
if(message.indexOf(hiTriggers[i]) >= 0) {
bot.sendMessage(SteamID, randomHelloMsg[Math stuff here blabla]); // randomHelloMsg is already defined
}
}
Regex wouldn't be used for this, right? As it is to be used for expressions or whatever. (my English isn't awesome, ikr)
Thanks in advance. If I wasn't clear enough on something, please let me know and I'll edit/formulate it in another way! :)
You can extend prototype:
String.prototype.regexIndexOf = function(regex, startpos) {
var indexOf = this.substring(startpos || 0).search(regex);
return (indexOf >= 0) ? (indexOf + (startpos || 0)) : indexOf;
}
and do:
var foo = "hia hi hello";
foo.regexIndexOf(/hi\b/);
Or if you don't want to extend the string object:
foo.substr(i).search(/hi\b/);
both examples where taken from the top answers of Is there a version of JavaScript's String.indexOf() that allows for regular expressions?
Regex wouldn't be used for this, right? As it is to be used for expressions or whatever. (my > English isn't awesome, ikr)
Actually, regex is for any old pattern matching. It's absolutely useful for this.
fmsf's answer should work for what you're trying to do, however, in general extending native objects prototypes is frowned upon afik. You can easily break libraries by doing so. I'd avoid it when possible. In this case you could use his regexIndexOf function by itself or in concert with something like:
//takes a word and searches for it using regexIndexOf
function regexIndexWord(word){
return regexIndexOf("/"+word+"\b/");
}
Which would let you search based on your array of words without having to add the special symbols to each one.

Basic Javascript String Manipulation

Hello there everyone,
I've been trying to figure out how to create a function that takes any input and adds spaces to it before returning it. For example. The function would change "hello" into "h e l l o"
When I perform the task -not- as a function, it seems to work okay. I previously had some good feedback about using the split() and join() functions and that seems to get the desired effect.
It just doesn't seem to be working as a function. Here is the code that I have come up with so far:
function sStr(aString)
{
var mySplitResult = aString.split("").join(" ");
return mySplitResult;
}
window.alert(sStr(test));
I would really appreciate any help with this as I'm racking my brains trying to learn this stuff. I can see that I still have a long way to go.
Put quotes around test like :
alert(sStr("test"));
In your code, test is not a string, but a variable. Strings need to be inserted in quotes or double quotes.
function sStr(aString)
{
return aString.split("").join(" ");
}
window.alert(sStr('test'));
Check this fiddle.
It works, just add quotes around test:
function sStr(aString)
{
var mySplitResult = aString.split("").join(" ");
return mySplitResult;
}
window.alert(sStr("test"));
It looks your function works beautifully. In this line:
window.alert(sStr(test));
Is test a variable, or did you mean to provide a string:
window.alert(sStr('test'));
While we're at it, you may want to make your function handle the cases where the (1) parameter is undefined or null and (2) the parameter is not a string (e.g.: numbers):
function sStr(aString)
{
if(!aString)
{
return "";
}
var mySplitResult = aString.toString().split("").join(" ");
return mySplitResult;
}

Grep a page in firefox using javascript

Am writing an extension to provide grep'ing functionality in Firefox. At my workplace we access all log files using a browser, and grep functionality would be ideal for filtering results, looking at only particular logging levels (INFO,WARN,ERROR) etc.
Have setup the extension boilerplate.
Was wondering if I could get some hints on the required javascript. Am after a function:
function grepPage(regex){
...
}
which would apply the regex to each line in loaded text file in firefox, and change the loaded text file to only display lines that match.
This is the type of thing I could spend ages trying to work out, when I'm sure there would be simpler ways of doing this.
Any help would be highly appreciated.
Cheers,
Ben
Two ways to look at this.
One, you could avoid re-inventing the wheel:
http://api.jquery.com/jQuery.grep/
Two, you could whip up a quick function (this example doesn't require jQuery or other libraries).
function grepPage(regex) {
var lines = document.getElementByTagName('body').innerHTML.split("\n");
var matches = new Array();
// Check if the regex is surrounded by slashes by checking for a leading slash
if ( ! regex.match(/^\//) ) { regex = '/' + regex + '/'; }
for (var i = 0; i < lines.length; i++) {
if ( regex.test( lines[i] ) ) { matches.push(lines[i]); }
}
// Now the 'matches' array contains all your matches, do as you will with it.
}
Warning, untested, but it should work. :)

Categories