JS and text encoding - javascript

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

Related

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

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

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

Loop through all the images inside directory and convert to base64

I am trying to loop through all the images in my folder convert it into base64 and send to MongoDB.
I started with one image, worked fine.
var filename = '1500.jpg';
var binarydata = fs.readFileSync(filename);
var converted = new Buffer(binarydata).toString("base64");
console.log(converted);
The above code gives me base64 for one file.
I tried changing the code so that it will loop through all the files in my directory and give me base64 for each file.
here is what I wrote but it did not work;
var variantfolder = './variantimages';
fs.readdir(variantfolder, function(err, files){
if (err) {
console.log(err);
}
else {
fs.readFileSync(files, function(err, res){
if (err){console.log('err')} else {
var converted = new Buffer(res).toString("base64");
var onevariant = {
"imagename":files,
"imagebase64":converted
}
var newvariant = new Variant(onevariant)
newvariant.save(err, newvar){
if (err) {
console.log('err');
}
else {
console.log('saved to mongo');
}
}
}
})
}
})
I suspect the problem will be related to you calling functions in the wrong ways.
Check the inputs and outputs of the functions you are using.
The fs.readdir() function callback is passed 2 parameters, an error and an array of file names.
The fs.readFileSync() function takes the parameters path and options. It also returns the file contents, it doesn't take a callback. The callback version is fs.readFile().
So in your code you are passing an array of file names into the file path parameter, which will not work.
You can also pass base64 as the encoding when reading the file and you won't have to convert it after.
I expect you will want something more along these lines (add your own error handling as required):
fs.readdir(variantfolder, (err, fileNames) => {
fileNames.forEach((fileName) => {
fs.readFile(`${variantfolder}/${fileName}`, 'base64', (err, base64Data) => {
// Do your thing with the file data.
});
});
});
Note that you can use the async, sync or promise (fs.promises) version of the fs functions depending on what is most suitable for your code.

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

How to build CDATA values in xml2js for node server?

I'm trying to parse a xml file and then change CDATA value of some nodes using xml2js. And then write the new xml document into that file. I've tried everything, but still not getting anywhere. I tried using string "" and "cdata" option in builder class. But it doesn't work. It always writes the text node as undefined i.e. [![CDATA[undefined]]
fs.readFile(xmlFileUrl, function(err, data) {
parser.parseString(data, function(err, result) {
//Change a node value to something .... and then build it
var xml = builder.buildObject(result);
fs.writeFile(xmlFileUrl), xml, function(err) {
if (err) {
console.log(err);
return;
}
});
});
});

Categories