Find X character at Y index in string and filter an array using this information

I got a string, and an array of strings. Examples of the string are:

let example1 = "_a_t_";
let example2 = "N_l_:t___";
let example3 = "B__z_l";

What we can see is that the string is Z characters long and got a random amount of characters that is not _. The string will never be only _ nor will it ever be without an underscore.

let array = ["Walts", "Grate", "Ralts", "Names"];

If we use the example1 string and the array above, I want to filter the array so the outcome becomes:

let newArray = ["Walts", "Ralts"];

Basically, of the known characters I want to use them and their position to filter the array. Currently I’ve found how to find the first character and use it to filter the array. This is how that was done:

let example1 = "_a_t_";
let array = ["Walts", "Grate", "Ralts", "Names"];

let charIndex = example1.match("[a-zA-Z]").index;
/*Currently using the RegEx [a-zA-Z], but this should be changed to include all characters 
besides underscores but I don't know what to put in between the square brackets*/
let firstChar = example1.charAt(charIndex);

let filteredArray = array.filter(function (element) {
  return element.charAt(charIndex) === firstChar;
});

console.log(filteredArray); //this returns ["Walts", "Ralts", "Names"]

It is here I am stuck. I got no idea how to do this if I got multiple revealed characters in the string. After pondering a bit, the logical thing to me would be to somehow count all the characters that’s not an underscore, then using that, make a loop. The loop would find each character and its index, then filter the array. The loop would finish when the array is completely filtered. Using the above array and example1 string, the wished goal would be to get ["Walts", "Ralts"].

I think that the problem is thoroughly explained, and that the end goal is clear. This is my first ever post on Stack Overflow so I’m very excited.

Answer

Another option could be to create a single regex and join all the words with in a non capture group with the | as a separator and do a single replacement for the _ to S to match a non whitespace char to not match spaces

The pattern will look like:

^(?:SaStS|NSlS:tSSS|BSSzSl)$

The pattern matches:

  • ^ Start of string
  • (?: Non capture group
    • SaStS First alternative, where S matches a non whitespace char
    • | Or
    • NSlS:tSSS Second alternative
    • | Or
    • BSSzSl Third alternative
  • ) Close non capture group
  • $ End of string

For example

let example1 = "_a_t_";
let example2 = "N_l_:t___";
let example3 = "B__z_l";
let array = ["Walts", "Grate", "Ralts", "Names"];
const strings = [example1, example2, example3];
const regex = new RegExp(`^(?:${strings.join("|").replace(/_/g, "\S")})$`);
console.log(array.filter(s => regex.test(s)));

If you want to match a space, you can use a . instead of S

Note that in the RegExp() constructor, you have to double escape the backslash. If any of the strings contain a character special to the regex, you have to escape those characters.

Another example:

const escapeRegExp = s => s.replace(/[-/\^$*+?.()|[]{}]/g, '\$&');
let example1 = "_a_t_";
let example2 = "N_l_:t___";
let example3 = "B__z_l";
let example4 = "T__()"
let array = ["Walts", "Grate", "Ralts", "Names", "Tab()"];
const strings = [example1, example2, example3, example4].map(s => escapeRegExp(s));
const regex = new RegExp(`^(?:${strings.join("|").replace(/_/g, ".")})$`);
console.log(array.filter(s => regex.test(s)));

Leave a Reply

Your email address will not be published. Required fields are marked *