How to identify a pattern in a string in nodejs - javascript

I have the following problem that I have not been able to solve for several hours:
What I want to do is that when I receive a string, identify a pattern in said string and be able to use it later, for example when receiving the text:
"Hello this is an example message, the hashtag of the day is #Phone, you can use it wherever you want"
what I want to do is identify that #Phone and extract it from all that text and for example then be able to make a console.log() of that word that is with the #. So that the result of the console.log is only Phone, for example, or the data that has the #
I have the following code:
const prefix = "#";
client.on("message", function(message) {
if (!message.content.includes(prefix)) return;
const commandBody = message.content.slice(prefix.length);
const args = commandBody.split(' ');
const command = args.shift().toUpperCase();
console.log(command)
});
This what returns me is the first element of the text without its first letter, in the case that the text is "Hello, how are you !try this", what it shows is only "ello", and I need it to only show " try"

Use a regular expression to match # (or !) followed by letters or non-space characters or whatever sort of text you want to permit afterwards:
const prefix = '!';
const pattern = new RegExp(prefix + '([a-z]+)', 'i');
const getMatch = str => str.match(pattern)?.[1];
console.log(getMatch('Hello, how are you !try this'));
If the prefix may be a special character in a regular expression, escape it first:
function escapeRegex(string) {
return string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
const pattern = new RegExp(escapeRegex(prefix) + '([a-z]+)', 'i');

Related

Replace substring with its exact length of another character

I am trying to replace a substring within a string with an exact number of other characters.
Example:
Input: Hello There, General Kenobie!
Output: xxxxx There, xxxxxxx Kenobie!
I can get this to work if I replace it with a preset string:
const text = "'Hello' There, 'General' Kenobie!"
const pattern = /(?:'([^']*)')|(?:"([^"]*)")/g;
console.log(text.replace(pattern, "xxx"));
Output: xxx There, xxx Kenobie!
What am I missing wrapping my head around.
Thanks!
You are using a hard-coded string of 'xxx' as your replacement string. So, that's what you are seeing... the string(s) replaced with 'xxx'.
The .replace() method actually supports a function as the replacement, instead of a string, so that's what you need here.
Docs: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_function_as_a_parameter
const text = "'Hello' There, 'General' Kenobie!"
const pattern = /(?:'([^']*)')|(?:"([^"]*)")/g;
const newText = text.replace(pattern, (str, m) => 'x'.repeat(m.length));
console.log(newText);
You can always loop through the matches and replace each separately.
let text = "'Hello' There, 'General' Kenobie!"
const pattern = /(?:'([^']*)')|(?:"([^"]*)")/g;
let array1;
while ((array1 = pattern.exec(text)) !== null) {
wrap = array1[0][0];
text = text.replace(array1[0],wrap + "x".repeat(array1[0].length-2) + wrap);
}
console.log(text)

Convert to small letters and remove space js

I am new to javascript currently working on discord bots
I coded a bot which responds to messages but when I give input in capital letters or by giving space the bot not responding please help me to fix this
This is my code and if I give input like "Hi bro"
It doesn't respond
bot.on("message", async message => {
if(message.author.bot || message.channel.type == 'dm') return;
let prefix = "-";
let messageArray = message.content.split(" ");
let cmd = messageArray[0];
let args = messageArray.slice(1);
if(cmd === `${prefix}hibro`) {
return message.reply("Hi bro!")
}
)}
Mostly your solution is to bring to the same format either making lowercase all the letters or capital. It's up to you, but better lowercase. Also you can use trim() to avoid multiple spaces.
const str = 'Whatever Text You Want';
const res = str.replace(/\s+/g,'').toLowerCase();
console.log(res)
Compare after making string lowercase. Example
var str = "Hello World!";
var res = str.toLowerCase();
If you want to convert all the letters to the small case then Javascript has toLowerCase() method available for strings. To replace the whitespace you can use the replace method.
So the following code will give the output: hibro!
"Hi bro!".toLowerCase().replace(/\s/g,'')
/\s/g finds all the occurrences of white space in the strings.
May be you can try the below,
const str1 = 'Whatever Text You Want';
var k=[...str1.toLocaleLowerCase()];
var s='';
k.forEach(temp=>{
s+=(temp!=' ')?temp:''
})
a.trim() only removes the trailing spaces at the end and the beginning of the string, it won't capture in between spaces.
May be you can refer about String.prototype.trim() MDN docs here
this shall do the trick.
if you get the message using message.content than replace all of the spaces with dashes using replaceAll and conver it to lower case with .toLowerCase()
message.content.replaceAll(' ', '-').toLowerCase()

How to make a dynamic regex in MongoDB?

I've come up with a regex to match terms that contain a certain phrase, which can include letters or numbers, and excludes a dash. For instance, test-123, test123 and test will all be matched by ^[test0-9._-]+$/gi.
However, in MongoDB, I'm not too sure how to dynamically search for it. I've tried,
const { search } = req.query;
const regex = new RegExp(`/^[${search}0-9._-]+$/`, "ig");
const results = await Test.find({ name: { $regex: regex } })
I've also tried
await Test.find({ name: { $regex: ".*[" + search + "0-9._-]+$.*", $options: "i" } })
As well as just,
const regex = new RegExp(`/^[${search}0-9._-]+$/`, "ig");
await Test.find({ name: regex });
Not sure how to get this working, what am I doing wrong?
Printing new RegExp(/^[${search}0-9._-]+$/, "ig") returns following pattern /\/^[test0-9._-]+$\//gi which is probably not what you're trying to achieve (additional slashes).
You can try this way (tested in Mongo Shell):
let search = "test";
let regex = new RegExp(`^[${search}0-9._-]+$`, "ig");
db.test.find({ name: { $regex: regex } });
NOTE:
You do not need to wrap the expression in "/" when using "new RegExp." Also, with expressions such as "\b" or anything with a backward slash, you may need to escape it with an extra "\"
For example:
const search = "string"
const regex = new RegExp(\\b${search}\\b, "i");
Prints out:
/\bstring\b/i

How can I ban a word

I want to replace a bad word with asterisks ***. However, there is a problem when the bad word is contained in an another word I don't want to replace it.
for(var i = 0; i < forbidden.length; i++) {
if(textBoxValue.search(forbidden[i]) > -1) {
textBoxValue = textBoxValue.replace(forbidden[i], '');
}
}
For example if the bad word is "are", if it is in another word like "aren't" I don't want it to appear as "***n't". I only want to replace the word if it is by itself.
One option is to use a regular expression with a word boundary on each side, to ensure that a matched word is standalone:
forbidden.forEach((word) => {
textBoxValue = textBoxValue.replace(new RegExp('\\b' + word + '\\b', 'g'), '');
});
For example:
let textBoxValue = 'bigwordfoo foo bar barbaz';
const forbidden = ['foo', 'bar'];
forbidden.forEach((word) => {
textBoxValue = textBoxValue.replace(new RegExp('\\b' + word + '\\b', 'g'), '');
});
console.log(textBoxValue);
If you actually want to replace with asterisks, and not the empty string, use a replacer function instead:
let textBoxValue = 'bigwordfoo foo bar barbaz';
const forbidden = ['foo', 'bar'];
forbidden.forEach((word) => {
textBoxValue = textBoxValue.replace(
new RegExp('\\b' + word + '\\b', 'g'),
word => '*'.repeat(word.length)
);
});
console.log(textBoxValue);
Of course, note that word restrictions are generally pretty easy to overcome by anyone who really wants to. Humans can almost always come up with ways to fool heuristics.
If any of the words to blacklist contain special characters in a regular expression, escape them first before passing to new RegExp:
const escape = s => s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
let textBoxValue = 'bigwordfoo foo ba$r ba$rbaz';
const forbidden = ['foo', 'ba$r'];
forbidden.forEach((word) => {
textBoxValue = textBoxValue.replace(
new RegExp('\\b' + escape(word) + '\\b', 'g'),
word => '*'.repeat(word.length)
);
});
console.log(textBoxValue);
You can create a dynamic regex with all the forbidden words separated by a | to create an alternation. You can wrap this with word boundary (\b) to replace only full word matches.
For the following list of forbidden words, the dynamic regex ends up being
/\b(?:bad|nasty|dreadful)\b/g
The second parameter to replace, gets the matched word as a parameter. You can use repeat to get * repeated the same number of times as the length of the word to be replaced
function replaceBadWords(textBoxValue, forbidden) {
const regex = new RegExp(`\\b(?:${forbidden.join('|')})\\b`, 'g')
return textBoxValue.replace(regex, m => "*".repeat(m.length))
}
const forbidden = ['bad', 'nasty', 'dreadful']
console.log(replaceBadWords('string with some nasty words in it', forbidden))
console.log(replaceBadWords("bad gets replaced with asterisks but badminton won't", forbidden))
If you're not yet using a library (Or if you want to use one)
You can check this repo out.
First, they already have a list of bad words so you don't need to think about them and think what you missed.
They support placeholders like:
var Filter = require('bad-words');
var customFilter = new Filter({ placeHolder: 'x'});
customFilter.clean('Don't be an ash0le'); //Don't be an xxxxxx
and you can add your own bad words like or remove it:
var filter = new Filter();
// add to list
filter.addWords('some', 'bad', 'word');
// remove from list
filter.removeWords('hells', 'sadist');
And also a multi lingual support if you have the correct regex.

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