Unexpected Behavior When Escaping Backslashes JS - javascript

so i'm making a simple function that separates the file name and the directory path. I believe there is an easier way with node's Path module but I thought i'd do it myself for this project.
so the problem is when i'm writing a backslash character in a string, I'm escaping them in the string like "directory\AnothaDirectory". It runs, but the double "\" and the "\\" used in order to escape are still remaining in the strings after they are parsed. ex: "C:\\Documents\Newsletters".
I have tried both to use single backslahses, which throws compiler errors as one could expect. but I have also tried to use forward slashes. what could be the reason the backslashes are not being escaped?
function splitFileNameFromPath(path,slashType){
let pathArray = path.split(slashType),
fileName = pathArray[pathArray.length - 1],
elsIndexes = pathArray.length - 1,
pathSegs = pathArray.slice(0, elsIndexes);
let dirPath = pathSegs.join(slashType);
//adds an extra slash after drive name and colon e.g."C:\\"
dirPath = dirPath.replace( new RegExp("/\\/","ug"), "\\" )
//removes illegal last slash
let pathSeg = pathSegs.slice(0,-1)
return [dirPath, fileName]
}
let res = splitFileNameFromPath("C:\\\\Documents\\Newsletters\\Summer2018.pdf","\\");
console.log(res)

There are some moments in this code I do not understand.
"C:\\\\Documents\\Newsletters\\Summer2018.pdf" (i.e. "C:\\Documents\Newsletters\Summer2018.pdf") does not seem like a valid Windows path as there are no double slashes after the drive letter usually used (it is not like in the URL 'https://...').
new RegExp("/\\/","ug") is equal to /\/\//gu and does not match anythhing.
The result of let pathSeg = pathSegs.slice(0,-1) is not used at all.
It seems to me this code is enough to achive the task:
'use strict';
function splitFileNameFromPath(path, slashType) {
const pathArray = path.split(slashType),
fileName = pathArray.pop(),
dirPath = pathArray.join(slashType);
return [dirPath, fileName];
}
const path = "C:\\Documents\\Newsletters\\Summer2018.pdf";
const slash = "\\";
const res = splitFileNameFromPath(path, slash);
console.log(res);
console.log(path === res.join(slash));

Related

NodeJS - Split the string of two joined paths, to obtain a certain portion of the string

Say we have a folder path like so...
/just/some/folder/location/
And a filepath like so...
this/way/for/the/file.txt
And we merge/join the two paths together to make a fullpath like so...
var folderPath = "/just/some/folder/location"
var filePath = "this/way/for/the/file.txt"
var joinedPath = path.join(folderPath, filePath);
How would I be able to cut the folderPath from the string, and keep only part of the filePath part so I'm left with an output like the example below?
way/for/the/file
As you already have the individual variables, do don't have to first join and then remove the value of folderPath.
Using filePath you could capture from the first occurrence of / to before the last occurrence of a . using a pattern
const regex = /\/(\S+)\./;
const str = `this/way/for/the/file.txt`;
const m = str.match(regex);
if (m) console.log(m[1]);
Thanks to #The fourth bird's answer, I was able to achieve what I wanted, I had to use a different method of joining the paths but it worked beautifully.
Code Below!
var folder = "/just/some/folder/location/"
var file = "this/way/to/the/file.txt"
var regex = /\/(\S+)\./;
var str = (folder, file) // different way of joining the paths
var m = str.match(regex);
var output = folder.split(folder).join(m[1]);
if (m) console.log(output);

How to parse JSON-like file with regex

I have this structure of my input data, it is just like JSON but not containing strings. I only need to parse few information from these data
{ .appVersion = "1230"; DisplayStrings = ( A ); customParameters = ( { name = Axes;.......(continues)}'''
the code looks like this, what happens here is that it matches but search until last appearance of semicolon. I tried all non-greedy tips and tricks that I have found, but I feel helpless.
const regex = /.appVersion = (".*"?);/
const found = data.match(regex)
console.log(found)
How can I access value saved under .appVersion variable, please?
You need to escape the . before appVersion since it is a special character in Regex and you can use \d instead of .* to match only digits. If you want just the number to be captured, without the quotes you can take them out of the parentheses.
const regex = /\.appVersion = "(\d+)";/
const found = data.match(regex)
const appVersion = found[1];
const string = '{ .appVersion = "1230"; DisplayStrings = (...(continues)';
const appVersion = string.match(/\.appVersion\s*=\s*"([^"]+)"/)[1];
If that's what you need...
I'm not sure where the format you're trying to parse comes from, but consider asking (making) your data provider return json string, so you could easily invoke JSON.parse() which works in both node and browser environments.
You can try the following:
var data='{ .appVersion = "1230"; DisplayStrings = ( A ); customParameters = ( { name = Axes;.......(continues)}';
const regex = /.appVersion = [^;]*/ //regex test: https://regex101.com/r/urX53f/1
const found = data.match(regex);
var trim = found.toString().replace(/"/g,''); // remove the "" if necessary
console.log(found.toString());
console.log(trim);
Your regex is looking for . which is "any character" in a regex. Escape it with a backslash:
/\.appVersion = ("\d+");/
Don't use .* to capture the value, It's greedy.
You can use something like \"[^\"]* - Match a quote, then Any character except quote, as many time as possible.
try
const regex = \.appVersion = \"([^\"]*)\";
Note that the first dot is should also be quoted, and the spaces should be exactly as in your example.

How to extract an ext from a filename having special chars in it-javascript

I am trying to get a the extension from a filename. The filename could include special characters, "#,#,.,_,(),..etc)
ex:
var file1 = "fake.der"
var file2 = "fake.1.der"
var file3 = "fake_test.3.der"
NOw In the above case I want to extract only the ext "der" from every filename.
I tried:
file1.split(".")[1] //works fine
file2.split(".")[1] // gives me 1 -incorrect but file2.split(".")[2] gives correct result
file3.split(".")[1] //gives 3-incorrect.
since filename could vary, I dont kinda want to make it the .split(".")[1] static, by changing it to .split(".")[2] for other filenames and so on..
HOw can I make sure that regardless of how many dots present in the filename, I'll always get the extension only as o/p, is there a better appraoch?
Thanks!
Use a regular expression to match a dot, followed by non-dot characters, followed by the end of the string:
function getExt(str) {
const match = str.match(/\.([^.]+)$/);
if (match) {
return match[1];
} else {
return 'Not found';
}
}
var file1 = "fake.der";
var file2 = "fake.1.der";
var file3 = "fake_test.3.der";
var file4 = "foobar";
[file1, file2, file3, file4].forEach(str => console.log(getExt(str)));
Note that you can't always be sure that an input string contains a well-formatted file extension, so make sure to handle those unexpected cases, as done above.
With lastIndexOf:
function getExtension(file) {
const index = file.lastIndexOf('.');
return index === -1 ? '' : file.slice(index + 1);
}
This also handles the case if the string does not contain a ..
you can use the \w in a regular expression which matches any "word" character. A "word" character is any letter or digit or the underscore character. You should use $ which starts marching from the back of the string
function ext(path) {
let extension = path.match(/\w+$/)
return extension ? extension[0].replace(".","") : null;
}
Just use .split() and some length calculations:
var file1 = "fake.der";
var file2 = "fake.1.der";
var file3 = "fake_test.3.der";
function getExtension(name) {
var nameArr = name.split(".");
var fileExt = nameArr[nameArr.length - 1];
return fileExt;
}
console.log(getExtension(file1));
console.log(getExtension(file2));
console.log(getExtension(file3));
Use slice ;)
const fileName = "file.name.extension.der";
console.log(fileName.split('.').slice(-1));

/: Unterminated groupregular expression: /R<f(9f

I have 2 very big txt files, file A contains some strings and on file B I have all the strings that i will search on file A.
Actually I turned file B into an array and with fs I loaded file A. The problem is that file B is containing some strange strings like R<f(9f so when I do match with regexp, the program exits with the error message /: Unterminated groupregular expression: /R<f(9f.
So what I want to do is that the regexp match "treats" the characters as strings and not as instructions.
console.time('program');
const fs = require('fs');
const filePath = "./processhackerfile.txt";
const hackStringsPath = "./hackstrings.txt";
var hackStrings = fs.readFileSync(hackStringsPath).toString().split("\n");
console.log(hackStrings.length);
var file = fs.readFileSync(filePath).toString();
for(i in hackStrings){
var regex = new RegExp(hackStrings[i].toString(), 'i');
var stringSearch = file.match(regex);
if(stringSearch != null){
console.log(`Cheat found, string name: ${stringSearch}`);
} else {
console.log('Cheat not found');
}
}
console.timeEnd('program');
You can find the code here
You need to escape the string to use in regular expression verbatim. Unfortunately there seems to be no built-in method to do that, however there are npm packages available for that, like this one: https://www.npmjs.com/package/escape-string-regexp

Use dynamic (variable) string as regex pattern in JavaScript

I want to add a (variable) tag to values with regex, the pattern works fine with PHP but I have troubles implementing it into JavaScript.
The pattern is (value is the variable):
/(?!(?:[^<]+>|[^>]+<\/a>))\b(value)\b/is
I escaped the backslashes:
var str = $("#div").html();
var regex = "/(?!(?:[^<]+>|[^>]+<\\/a>))\\b(" + value + ")\\b/is";
$("#div").html(str.replace(regex, "" + value + ""));
But this seem not to be right, I logged the pattern and its exactly what it should be.
Any ideas?
To create the regex from a string, you have to use JavaScript's RegExp object.
If you also want to match/replace more than one time, then you must add the g (global match) flag. Here's an example:
var stringToGoIntoTheRegex = "abc";
var regex = new RegExp("#" + stringToGoIntoTheRegex + "#", "g");
// at this point, the line above is the same as: var regex = /#abc#/g;
var input = "Hello this is #abc# some #abc# stuff.";
var output = input.replace(regex, "!!");
alert(output); // Hello this is !! some !! stuff.
JSFiddle demo here.
In the general case, escape the string before using as regex:
Not every string is a valid regex, though: there are some speciall characters, like ( or [. To work around this issue, simply escape the string before turning it into a regex. A utility function for that goes in the sample below:
function escapeRegExp(stringToGoIntoTheRegex) {
return stringToGoIntoTheRegex.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
var stringToGoIntoTheRegex = escapeRegExp("abc"); // this is the only change from above
var regex = new RegExp("#" + stringToGoIntoTheRegex + "#", "g");
// at this point, the line above is the same as: var regex = /#abc#/g;
var input = "Hello this is #abc# some #abc# stuff.";
var output = input.replace(regex, "!!");
alert(output); // Hello this is !! some !! stuff.
JSFiddle demo here.
Note: the regex in the question uses the s modifier, which didn't exist at the time of the question, but does exist -- a s (dotall) flag/modifier in JavaScript -- today.
If you are trying to use a variable value in the expression, you must use the RegExp "constructor".
var regex = "(?!(?:[^<]+>|[^>]+<\/a>))\b(" + value + ")\b";
new RegExp(regex, "is")
I found I had to double slash the \b to get it working. For example to remove "1x" words from a string using a variable, I needed to use:
str = "1x";
var regex = new RegExp("\\b"+str+"\\b","g"); // same as inv.replace(/\b1x\b/g, "")
inv=inv.replace(regex, "");
You don't need the " to define a regular expression so just:
var regex = /(?!(?:[^<]+>|[^>]+<\/a>))\b(value)\b/is; // this is valid syntax
If value is a variable and you want a dynamic regular expression then you can't use this notation; use the alternative notation.
String.replace also accepts strings as input, so you can do "fox".replace("fox", "bear");
Alternative:
var regex = new RegExp("/(?!(?:[^<]+>|[^>]+<\/a>))\b(value)\b/", "is");
var regex = new RegExp("/(?!(?:[^<]+>|[^>]+<\/a>))\b(" + value + ")\b/", "is");
var regex = new RegExp("/(?!(?:[^<]+>|[^>]+<\/a>))\b(.*?)\b/", "is");
Keep in mind that if value contains regular expressions characters like (, [ and ? you will need to escape them.
I found this thread useful - so I thought I would add the answer to my own problem.
I wanted to edit a database configuration file (datastax cassandra) from a node application in javascript and for one of the settings in the file I needed to match on a string and then replace the line following it.
This was my solution.
dse_cassandra_yaml='/etc/dse/cassandra/cassandra.yaml'
// a) find the searchString and grab all text on the following line to it
// b) replace all next line text with a newString supplied to function
// note - leaves searchString text untouched
function replaceStringNextLine(file, searchString, newString) {
fs.readFile(file, 'utf-8', function(err, data){
if (err) throw err;
// need to use double escape '\\' when putting regex in strings !
var re = "\\s+(\\-\\s(.*)?)(?:\\s|$)";
var myRegExp = new RegExp(searchString + re, "g");
var match = myRegExp.exec(data);
var replaceThis = match[1];
var writeString = data.replace(replaceThis, newString);
fs.writeFile(file, writeString, 'utf-8', function (err) {
if (err) throw err;
console.log(file + ' updated');
});
});
}
searchString = "data_file_directories:"
newString = "- /mnt/cassandra/data"
replaceStringNextLine(dse_cassandra_yaml, searchString, newString );
After running, it will change the existing data directory setting to the new one:
config file before:
data_file_directories:
- /var/lib/cassandra/data
config file after:
data_file_directories:
- /mnt/cassandra/data
Much easier way: use template literals.
var variable = 'foo'
var expression = `.*${variable}.*`
var re = new RegExp(expression, 'g')
re.test('fdjklsffoodjkslfd') // true
re.test('fdjklsfdjkslfd') // false
Using string variable(s) content as part of a more complex composed regex expression (es6|ts)
This example will replace all urls using my-domain.com to my-other-domain (both are variables).
You can do dynamic regexs by combining string values and other regex expressions within a raw string template. Using String.raw will prevent javascript from escaping any character within your string values.
// Strings with some data
const domainStr = 'my-domain.com'
const newDomain = 'my-other-domain.com'
// Make sure your string is regex friendly
// This will replace dots for '\'.
const regexUrl = /\./gm;
const substr = `\\\.`;
const domain = domainStr.replace(regexUrl, substr);
// domain is a regex friendly string: 'my-domain\.com'
console.log('Regex expresion for domain', domain)
// HERE!!! You can 'assemble a complex regex using string pieces.
const re = new RegExp( String.raw `([\'|\"]https:\/\/)(${domain})(\S+[\'|\"])`, 'gm');
// now I'll use the regex expression groups to replace the domain
const domainSubst = `$1${newDomain}$3`;
// const page contains all the html text
const result = page.replace(re, domainSubst);
note: Don't forget to use regex101.com to create, test and export REGEX code.
var string = "Hi welcome to stack overflow"
var toSearch = "stack"
//case insensitive search
var result = string.search(new RegExp(toSearch, "i")) > 0 ? 'Matched' : 'notMatched'
https://jsfiddle.net/9f0mb6Lz/
Hope this helps

Categories