NodeJS - Regex to match a specific string containing numbers (Closed) - javascript

Say I have a file called test.txt which is fixed with nonsense text.
But among this text is a specific string containing numbers in single quotes ('') like so;
blahblahblah:
Blahblahblah:
targetNumber: '30' <== target numbers
Blahblahblah
How would I go about replacing only these single quoted numbers, without replacing the entire file contents like so;
blahblahblah:
Blahblahblah:
targetNumber: '22' <== changed numbers
Blahblahblah
So far the regex functions I've constructed using numerous other questions on StackOverflow don't seem want to work and if they do work, they don't work as expected because they always seem to replace the entire contents of the file rather than just that set of numbers.
My last regex attempt on this is below, but it doesn't work, it just replaces the entire file contents so I don't where I'm going wrong, I'm still learning regex currently, can anyone please help???
var folder = "just/a/test/folder";
fs.readFile(path.join(folder, 'test.txt'), 'utf8', (error, data) => {
if (error) {
console.log('Unable to Read File');
return;
};
var regex = /'\d{1,2}\'/
var str = data.substring(data.indexOf("targetNumber: ") + 14);
var m = str.match(regex)
var replace = str.replace(m[1], "22");
fs.writeFile(path.join(folder, 'test.txt'), replace, 'utf8', (error) => {
if (error) {
console.log('Modifying File failed')
return;
}
});

You should do the replacement over the data and then you can capture targetNumber: in a group, using that group again with $1 in the replacement followed by your replacement.
See the match and the replacement at this regex demo.
const folder = "just/a/test/folder";
const file = 'test.txt'
fs.readFile(path.join(folder, file), 'utf8', (error, data) => {
if (error) {
console.log('Unable to Read File');
return;
}
const regex = /\b(targetNumber:\s*')\d{1,2}'/g;
const replace = data.replace(regex, "$122'");
fs.writeFile(path.join(folder, file), replace, 'utf8', (error) => {
if (error) {
console.log('Modifying File failed')
}
});
});

Related

Retrieve a pdf's bookmark data using VanillaJS/Node.js

I'm trying to retrieve a pdf's meta data, looking specifically for a bookmark's page number using VanillaJS/node.js with no libraries. The file is located locally on the desktop.
I found this bit of code in another answer but it only returns the length of the document. I have tried to change the regex to look for letters, but if then returns an array of 500000 letters.
Is it even possible? If libraries are required, does anyone know of one that can do this?
Thanks
const fs = require('fs').promises
let rawData = await fs.readFile(fullPath, 'utf8', (err, data) => {
if (err) {
console.error('test error', err);
return;
}
});
async function pdfDetails(data) {
return new Promise(done => {
let Pages2 = data.match(/[a-zA-Z]/g);
let regex = /<xmp.*?:(.*?)>(.*?)</g;
let meta = [{
Pages
}];
let matches = regex.exec(data);
while (matches != null) {
matches.shift();
meta.push({
[matches.shift()]: matches.shift()
});
matches = regex.exec(data);
}
done(meta);
});
}
let details = await pdfDetails(rawData)
console.log(details)
Due to the difficulty of using vanilla JS, and problems with libraries that may have worked (due to node version conflicts), I ended up using PDFTron services.

Deleting a line in a txt file with Node.js

I recently made a script in which I want to delete an EXACT match from a txt file with node. It print's out true but doesn't actually remove the line from the txt file. I am using discord to get the argument.
I'm not sure what I'm doing wrong but here is my script:
const fs = require('fs')
fs.readFile('notredeemed.txt', function (err, data) {
if (err) throw err;
if (data.toString().match(new RegExp(`^${args[0]}$`, "m"))) {
fs.readFile('notredeemed.txt', 'utf8', function (err,data) {
if (err) {
return console.log(err);
}
var result = data.replace(/${args[0]/g, '');
fs.writeFile('notredeemed.txt', result, 'utf8', function (err) {
if (err) return console.log(err);
});
});
console.log("true")
If someone could help me I would appreciate it :)
I think you can do it very similarly as your current solution, just the regex is a little off.
Instead of just using ^ and $ to indicate that the entire string starts and ends with the args[0], I used two capture groups as the delimiters of a line.
This one matches any newline character or the beginning of the string. Works for first line of file, and prevents partial replacement e.g. llo replacing Hello:
(\n|^)
And this one matches a carriage return or the end of the string. This works for cases where there is no newline at the end of the file, and also prevents Hel replacing Hello:
(\r|$)
That should ensure that you are always taking out an entire line that matches your args.
I also eliminated the second readFile as it wasn't necessary to get it to work.
const fs = require("fs")
fs.readFile("notredeemed.txt", function (err, data) {
if (err) throw err
const match = new RegExp(`(\n|^)${args[0]}(\r|$)`)
const newFile = data.toString().replace(match, ``)
fs.writeFile("notredeemed.txt", newFile, "utf8", function (err) {
if (err) return console.log(err)
console.log("true")
})
})
Here is my solution.
Algorithm:
Split the file content into individual lines with your desired End of Line Flag (generally "\n" or "\r\n")
Filter all the lines that you want to delete
Join all the filtered lines back together with the EOL flag
const replacingLine = "- C/C++ addons with Node-API";
const fileContent = `- V8
- WASI
- C++ addons
- C/C++ addons with Node-API
- C++ embedder API
- C/C++ addons with Node-API
- Corepack`;
const newFileContent = replace({ fileContent, replacingLine });
console.log(newFileContent);
function replace({ fileContent, replacingLine, endOfLineFlag = "\n" }) {
return fileContent
.split(endOfLineFlag)
.filter((line) => line !== replacingLine)
.join(endOfLineFlag);
}

Verify if word exist in file.txt

i have this script, who i run in a program called discord bot maker. I'm trying to give the bot the possibility to search for a word in a txt file, then remove this word and save the file :
let fs = require('fs');
let a = tempVars('a');
let b = tempVars('carte');
fs.readFile(`resources/${a}.txt`, { encoding: 'utf-8' }, (err, data) => {
if (err) throw err;
let dataArray = data.split('\n'); // convert file data in an array
const searchKeyword = `${b}`; // we are looking for a line, contains, key word 'user1' in the file
const key = dataArray.filter((arr) => arr.includes(searchKeyword));
const index = key.length >= 1 && dataArray.indexOf(key[0]);
if (index > -1) dataArray.splice(index, 1);
// UPDATE FILE WITH NEW DATA
// IN CASE YOU WANT TO UPDATE THE CONTENT IN YOUR FILE
// THIS WILL REMOVE THE LINE CONTAINS 'user1' IN YOUR shuffle.txt FILE
const updatedData = dataArray.join('\n');
fs.writeFile(`resources/${a}.txt`, updatedData, (writeErr) => {
if (writeErr) throw err;
console.log('Successfully updated the file data');
});
});
the tempVars("xx") variables are given by a program named discord bot maker, so no trouble with that.
My problem is that when the var "b" (who is the parameter of a command in discord) doesnt exist in the txt file, the script delete the first word in the file !
How can i add a condition to this script (If b dont exist in file, stop the script and return a message)
thank you very mutch guys ! have a good day
You can use use replace method without converting file into arrays.
let fs = require('fs');
let a = tempVars('a');
let b = tempVars('carte');
fs.readFile(`resources/${a}.txt`, { encoding: 'utf-8' }, (err, data) => {
if (err) throw err;
const updatedData = data.replace(b, '');
fs.writeFile(`resources/${a}.txt`, updatedData, (writeErr) => {
if (writeErr) throw err;
console.log('Successfully updated the file data');
});
});
This method will replace only first matched word. In case, if you want to replace all matched word, as a first parameter, you can use Regular Expression.
Char g is stands for global, m is for multi-line.
const regex = new RegExp(b, 'gm')
data.replace(regex, '');
In case you want to test if the file contains requested word, you can use .includes function and if statement.
if (!data.includes(b)) {
console.log("Requested word is not present in file")
// Your logic here
return
}

How do you use a forward slash in a regex search?

I am trying to find and replace all text in between comments in my react component using regex.
This is an example of the react component with comments:
<Text>{/*text1*/}hey hey hey{/*text1*/}</Text>
I am able to replace the text if I change {/*text1*/} to {text1}. The issue is whenever I try to add the /* */ part of the comment into my regex it keeps adding an extra backslash.
Below is my current function that works if I remove the /* and */ from the comment in my component:
async function doIt(fileName, location, replacementText) {
let tempRegex = "(?<={" + location + "})(.*)(?={" + location + "})"
let regex = new RegExp(tempRegex)
await fs.readFile(path.join(__dirname, fileName), 'utf8', function (err, data) {
if (err) throw err
content = data
content = content.replace(regex, replacementText)
fs.writeFile(path.join(__dirname, fileName), content, 'utf8', function (err) {
if (err) throw err
console.log('FILE SAVED')
})
})
}
doIt('change.js', "text1", 'test test')
My idea was to change my tempRegex to:
"(?<={/*" + location + "*/})(.*)(?={/*" + location + "*/})"
but it keeps adding extra characters and looks like this:
/(?<={\/*textBox1*\/})(.*)(?={\/*textBox1*\/})/
Is there a way to add forward slashes without it adding an extra backslash?
The forward slash / is a special character in regular expressions, because it denotes the beginning and the end of them. In case you want to target a forward slash inside your RegExp you have to escape it. That's what the backslashes do.
So this regular expression is invalid:
/{//
Whereas this one is valid:
/{\//
I just realized my issue was that new RegExp was not escaping the asterisk. This was my final solution. I had to add 2 backslashes in front of the asterisk for it to work.
export default function updateText(fileName, location, replacementText) {
let tempRegex = "(?<={/\\*" + location + "\\*/})(.*)(?={/\\*" + location + "\\*/})"
let regex = new RegExp(tempRegex)
fs.readFile(path.join(__dirname, fileName), 'utf8', function (err, data) {
if (err) throw err
content = data
content = content.replace(regex, replacementText)
fs.writeFile(path.join(__dirname, fileName), content, 'utf8', function (err) {
if (err) throw err
console.log('FILE SAVED')
})
})
}

JS and text encoding

I have a text file with accented characters like é. I used File Encoding Checker, it appears that the file is encoded as windows-1252.
I read the file with the following JS and node.js code:
fs.readFile('frenchVerbsList.txt','utf-8', function(err, data) {
if (err) {
return console.log("ERROR here!: " + err);
}
frenchWords = data.split('\r\n');
console.log(frenchWords);
});
The output from the console.log statement shows a question mark instead of the accented characters.
What has happened?
Node only supports some encodings and windows-1252 is not part of it. You need to convert the encoding with, for example, encoding to, for example, utf-8.
Similar to this, but haven't tested
var encoding = require("encoding");
fs.readFile('frenchVerbsList.txt', function(err, text) {
if (err) return console.log("ERROR here!: " + err);
var resultBuffer = encoding.convert(text, 'utf8', 'windows1252');
frenchWords = resultBuffer.toString().split('\r\n');
console.log(frenchWords);
})

Categories