Javascript regex pattern array with loop - javascript

I have attempted to create a function that will replace multiple regular expression values from an array. This works if the array does not contain quotation marks of any kind, this is problematic when I want to use a comma in my pattern. So I've been trying to find an alternative way of serving the pattern with no luck. Any ideas?
function removeCharacters(str){
//ucpa = unwanted character pattern array
//var ucpa = [/{/g,/}/g,/--/g,/---/g,/-/g,/^.\s/];
var ucpa = ["/{/","/}/","/--/","/---/","/-/","/^.\s/","/^,\s/"];
for (var i = 0; i < ucpa.length; i++){
//does not work
var pattern = new RegExp(ucpa[i],"g");
var str = str.replace(pattern, " ");
}
return str;
}
WORKING:
function removeCharacters(str){
//ucpa = unwanted character pattern array
var ucpa = [/{/g,/}/g,/--/g,/---/g,/-/g,/^.\s/,/^,\s/];
for (var i = 0; i < ucpa.length; i++){
var str = str.replace(ucpa[i], " ");
}
return str;
}
REFINED:
function removeCharacters(str){
var pattern = /[{}]|-{1,3}|^[.,]\s/g;
str = str.replace(pattern, " ");
return str;
}

The RegExp constructor takes raw expressions, not wrapped in / characters.
Therefore, all of your regexes contain two /s each, which isn't what you want.
Instead, you should make an array of actual regex literals:
var ucpa = [ /.../g, /",\/.../g, ... ];

You can also wrap all that into a single regex:
var str = str.replace(/[{}]|-{1,3}|^[.,]\s/g, " ")
although I'm not sure if that's exactly what you want since some of your regexes are nonsensical, for example ,^\s could never match.

Related

Javascript regex to add to every character of a string a backslash

So as the title says I'd like to add to every character of a string a backslash, whether the string has special characters or not. The string should not be considered 'safe'
eg:
let str = 'dj%^3&something';
str = str.replace(x, y);
// str = '\d\j\%\^\3\&\s\o\m\e\t\h\i\n\g'
You could capture every character in the string with (.) and use \\$1 as replacement, I'm not an expert but basically \\ will render to \ and $1 will render to whatever (.) captures.
HIH
EDIT
please refer to Wiktor Stribiżew's comment for an alternative which will require less coding. Changes as follows:
str = str.replace(/(.)/g, '\\$1'); for str = str.replace(/./g, '\\$&');
Also, for future reference I strongly advice you to visit regexr.com when it comes to regular expressions, it's helped ME a lot
let str = 'dj%^3&something';
str = str.replace(/(.)/g, '\\$1');
console.log(str);
If you just want to display a string safely, you should just do:
let str = 'dj%^3&something';
let node = document.createTextNode(str);
let dest = document.querySelector('.whatever');
dest.appendChild(node);
And then you are guaranteed that it will be treated as text, and won't be able to execute a script or anything.
For example: https://jsfiddle.net/s6udj03L/1/
You can split the string to an array, add a \ to each element to the array, then joint the array back to the string that you wanted.
var str = 'dj%^3&something';
var split = str.split(""); // split string into array
for (var i = 0; i < split.length; i++) {
split[i] = '\\' + split[i]; // add backslash to each element in array
}
var joint = split.join('') // joint array to string
console.log(joint);
If you don't care about creating a new string and don't really have to use a regex, why not just iterate over the existing one and place a \ before each char. Notice to you have to put \\ to escape the first \.
To consider it safe, you have to encode it somehow. You could replace typical 'non-safe' characters like in the encode() function below. Notice how & get's replaced by &
let str = 'dj%^3&something';
let out = "";
for(var i = 0; i < str.length; i++) {
out += ("\\" + str[i]);
}
console.log(out);
console.log(encode(out));
function encode(string) {
return String(string).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
}

Splitting string into matching and non-matching groups in javascript

I am trying to split the string into an array of strings those matching a regular expression and those that don't:
string = "Lazy {{some_animal}} jumps over.."
# do some magic with regex /({{\s?[\w]+\s?}})/g and its negation
array = ["Lazy ", "{{some_animal}}", " jumps over.."]
Best performant way to do that in javascript?
You can use String match for that
The regex below simply matches anything that's not a mustach, optionally surrounded by mustaches.
Example snippet:
var str = "Lazy {{some_animal}} jumps over..";
const pattern = /\{*[^{}]+\}*/g;
var array = str.match(pattern);
console.log(str);
console.log(pattern);
console.log(array);
But to make it more precise, the regex pattern becomes a bit more complicated.
The regex below matches:
"what you want"
(a word between 2 mustaches on each side)
OR "what you don't want followed by what you want"
(using lazy matching and positive lookahead)
OR "what remains"
var str = "Lazy {{some_animal}} jumps over..";
const pattern = /\{\{\w+\}\}|.+?(?=\{\{\w+\}\})|.+/g;
var array = str.match(pattern);
console.log(str);
console.log(pattern);
console.log(array);
And last but not least, the evil SM method.
Split AND Match on the same regex. And concatinate them into a single array.
The downside of this method is that the order is not preserved.
var str = "Lazy {{some_animal}} jumps over..";
const pattern = /\{\{\w+\}\}/g;
var what_you_want = str.match(pattern);
var what_you_dont_want = str.split(pattern);
var array = what_you_want.concat(what_you_dont_want);
console.log(str);
console.log(pattern);
console.log(array);
I'm fairly sure a simple exec loop is going to be your best option:
function getSegments(rex, str) {
var segments = [];
var lastIndex = 0;
var match;
rex.lastIndex = 0; // In case there's a dangling previous search
while (match = rex.exec(str)) {
if (match.index > lastIndex) {
segments.push(str.substring(lastIndex, match.index));
}
segments.push(match[0]);
lastIndex = match.index + match[0].length;
}
if (lastIndex < str.length) {
segments.push(str.substring(lastIndex));
}
return segments;
}
var rex = /{{\s?[\w]+\s?}}/g;
var string = "Lazy {{some_animal}} jumps over..";
console.log(getSegments(/{{\s?[\w]+\s?}}/g, string));
Note I removed the capture group; it's not needed for this sort of solution.

Javascript get query string values using non-capturing group

Given this query string:
?cgan=1&product_cats=mens-jeans,shirts&product_tags=fall,classic-style&attr_color=charcoal,brown&attr_size=large,x-small&cnep=0
How can I extract the values from only these param types 'product_cat, product_tag, attr_color, attr_size' returning only 'mens-jeans,shirts,fall,classic-style,charcoal,brown,large,x-small?
I tried using a non-capturing group for the param types and capturing group for just the values, but its returning both.
(?:product_cats=|product_tags=|attr\w+=)(\w|,|-)+
You can collect tha values using
(?:product_cats|product_tags|attr\w+)=([\w,-]+)
Mind that a character class ([\w,-]+) is much more efficient than a list of alternatives ((\w|,|-)*), and we avoid the issue of capturing just the last single character.
Here is a code sample:
var re = /(?:product_cats|product_tags|attr\w+)=([\w,-]+)/g;
var str = '?cgan=1&product_cats=mens-jeans,shirts&product_tags=fall,classic-style&attr_color=charcoal,brown&attr_size=large,x-small&cnep=0';
var res = [];
while ((m = re.exec(str)) !== null) {
res.push(m[1]);
}
document.getElementById("res").innerHTML = res.join(",");
<div id="res"/>
You can always use a jQuery method param.
You can use following simple regex :
/&\w+=([\w,-]+)/g
Demo
You need to return the result of capture group and split them with ,.
var mystr="?cgan=1&product_cats=mens-jeans,shirts&product_tags=fall,classic-style&attr_color=charcoal,brown&attr_size=large,x-small&cnep=0
";
var myStringArray = mystr.match(/&\w+=([\w,-]+)/g);
var arrayLength = myStringArray.length-1; //-1 is because of that the last match is 0
var indices = [];
for (var i = 0; i < arrayLength; i++) {
indices.push(myStringArray[i].split(','));
}
Something like
/(?:product_cats|product_tag|attr_color|attr_size)=[^,]+/g
(?:product_cats|product_tag|attr_color|attr_size) will match product_cats or product_tag or attr_color or attr_size)
= Matches an equals
[^,] Negated character class matches anything other than a ,. Basically it matches till the next ,
Regex Demo
Test
string = "?cgan=1&product_cats=mens-jeans,shirts&product_tags=fall,classic-style&attr_color=charcoal,brown&attr_size=large,x-small&cnep=0";
matched = string.match(/(product_cats|product_tag|attr_color|attr_size)=[^,]+/g);
for (i in matched)
{
console.log(matched[i].split("=")[1]);
}
will produce output as
mens-jeans
charcoal
large
There is no need for regular expressions. just use splits and joins.
var s = '?cgan=1&product_cats=mens-jeans,shirts&product_tags=fall,classic-style&attr_color=charcoal,brown&attr_size=large,x-small&cnep=0';
var query = s.split('?')[1],
pairs = query.split('&'),
allowed = ['product_cats', 'product_tags', 'attr_color', 'attr_size'],
results = [];
$.each(pairs, function(i, pair) {
var key_value = pair.split('='),
key = key_value[0],
value = key_value[1];
if (allowed.indexOf(key) > -1) {
results.push(value);
}
});
console.log(results.join(','));
($.each is from jQuery, but can easily be replaced if jQuery is not around)

search for keyword in extracted text javascript

So I managed to extract some text, and then I saved it as a variable for later use, how can I test for certain keywords within said text?
Here's an example, checkTitle is the text I extracted, and I want to search it for certain keywords, in this example, the words delimited by commas within compareTitle. I want to search for the strings '5' and 'monkeys'.
var checkTitle = "5 monkeys jumping on the bed";
var compareTitle = "5 , monkeys";
if (checkTitle === compareTitle) {
// ...
}
You can use regular expressions to search for strings, and the test() function to return true/false if the string contains the words.
/(?:^|\s)(?:(?:monkeys)|(?:5))\s+/gi.test("5 monkeys jumping on the bed");
will return true, because the string contains either (in this case, both) the words 5 and monkeys.
See my example here: http://regexr.com/39ti7 to use the site's tools to analyse each aspect of the regular expression.
If you need to change the words you are testing for each time, then you can use this code:
function checkForMatches(){
var words = checkTitle.split(" , ");
var patt;
for (var i = 0; i < words.length; i++){
patt = patt + "(" + words[i] + ")|";
}
patt[patt.length-1] = "";
patt = new RegExp(patt, "i");
return patt.test(checkTitle);
}
will return true, and allow for any words you want to be checked against. They must be separated like this:
compareText = "word1 , word2 , word3 , so on , ...";
// ^^^notice, space-comma-space.
And you can use it in an if statement like this:
var checkTitle = "5 monkeys jumping on the bed";
var compareTitle = "5 , monkeys";
if (checkForMatches()){
//a match was found!
}
Using the String.prototype.contains() method you can search for substrings within strings. For example,
"Hi there everyone!".contains("Hi"); //true
"Hi there everyone!".contains("there e"); //true
"Hi there everyone!".contains("goodbye"); //false
You can also use Array.prototype.indexOf() to a similar effect:
("Hi there everyone!".indexOf("Hi") > -1) //true
("Hi there everyone!".indexOf("Hmmn") > -1) //false
However, in this method, we don't even need to use any of the above methods, as the .match() method will do it all for us:
To return an array of the matched keywords, use .match(). It accepts a regular expression as an argument, and returns an array of substrings which match the regular expression.
var checkTitle = "5 monkeys jumping on the bed";
var compareTitle = "5 , monkeys";
/* ^^^
It is very important to separate each word with space-comma-space */
function getWords(str){ //returns an array containing key words
return str.split(" , ");
}
function matches(str, words){
var patt = "";
for (var i = 0; i < words.length; i++){
patt = (i > 0)? patt + "|" + "(" + words[i] + ")" : patt + "(" + words[i] + ")";
}
patt[patt.length-1] = "";
patt = new RegExp(patt, 'gi');
// ^ i makes it case-insensitive
return str.match(patt);
}
matches(compareTitle, getWords(checkTitle)); // should return ['5','monkeys']
you can check if a match exists by doing this:
if (matches(compareTitle, getWords(checkTitle))){
// matches found
}
If this answer is better than the first, accept this one instead. Ask for any more help, or if it doesn't work.

Regex remove repeated characters from a string by javascript

I have found a way to remove repeated characters from a string using regular expressions.
function RemoveDuplicates() {
var str = "aaabbbccc";
var filtered = str.replace(/[^\w\s]|(.)\1/gi, "");
alert(filtered);
}
Output: abc
this is working fine.
But if str = "aaabbbccccabbbbcccccc" then output is abcabc.
Is there any way to get only unique characters or remove all duplicates one?
Please let me know if there is any way.
A lookahead like "this, followed by something and this":
var str = "aaabbbccccabbbbcccccc";
console.log(str.replace(/(.)(?=.*\1)/g, "")); // "abc"
Note that this preserves the last occurrence of each character:
var str = "aabbccxccbbaa";
console.log(str.replace(/(.)(?=.*\1)/g, "")); // "xcba"
Without regexes, preserving order:
var str = "aabbccxccbbaa";
console.log(str.split("").filter(function(x, n, s) {
return s.indexOf(x) == n
}).join("")); // "abcx"
This is an old question, but in ES6 we can use Sets. The code looks like this:
var test = 'aaabbbcccaabbbcccaaaaaaaasa';
var result = Array.from(new Set(test)).join('');
console.log(result);

Categories

Resources