I asked a pretty detailed question earlier but it got flagged as a duplicate even though it wasn't.
So I will try and explain what I am trying to do as simply as I can. I want to search a text string for words that begin with specific letters such as "mak", "mind" and "mass" (which are in an array) and end with either nothing extra or "e" or "er". That would be in this instance "mak", "make", "maker", "mind", "minde", "minder", "mass", "masse", "masser".
The code I am using only finds the first match for each word in the array, for instance "mak", "mind" and "mass" in the example.
derPro = ['mak','mind', 'mass', ;
for(i = 0; i < derPro.length; i++){
searchTerm = new RegExp(
"\\b" + derPro[i] + "\\b|" +
"\\b" + derPro[i] + "e\\b|" +
"\\b" + derPro[i] + "er\\b,'gi'");
word = testText.match(searchTerm, "gi");
This should work:
var derPro = ['mak','mind', 'mass'];
var searchTerm = new RegExp('\\b((?:' + derPro.join('|') + ')(?:er?)?)\\b', "gi");
//=> /\b((?:mak|mind|mass)(?:er?)?)\b/gi
// now match the regex in a while loop
var matches=[]
while (m = searchTerm.exec('mass maker minde')) matches.push(m[1]);
console.log(matches);
//=> ["mass", "maker", "minde"]
Get the matched group from index 1.
/(\b(mak|mind|mass)(e|er)?\b)/gi
Online demo
This works, i know you asked for a regex, but I thought this would be useful.
var keys = [
'mak',
'mind',
'mass'
];
var test_words = [
'mak',
'make',
'maker',
'mind',
'mass'
];
var matches = [];
for(var i = 0; i < keys.length; i++) {
var key = keys[i];
for(var ii = 0; ii < test_words.length; ii++) {
var test_word = test_words[ii];
if(test_word.substr(0, key.length) == key) {
if( test_word.substr(-1) == 'e' || test_word.substr(-2) == 'er') {
matches.push(test_word);
}
}
}
}
console.log(matches);
// [make, maker, minde]
jsfiddle
Related
how to return isValid = false when test(E) for both regex
let arr =[A_MANAGER,B_MANAGER,C_MANAGER,A_EMPLOYEE,C_EMPLOYEE]
arr.map((item)=>{
let isValid = ( new RegExp("MANAGER").test(item) && !new RegExp("EMPLOYEE").test(item))
console.log(isValid)
})
problem statement
let M= MANAGER, E=EMPLOYEE
M M = true
M E = true
E M = true
E E =false
One approach would be to parse the input array into two separate arrays of employees and managers. Then, starting with a collection of all people, detect whether or not a person be a manager and employee at the same time.
var arr = ["A_MANAGER", "B_MANAGER", "C_MANAGER", "A_EMPLOYEE", "C_EMPLOYEE"];
var employees = [];
var managers = [];
var all = ["A", "B", "C"];
for (var i=0; i < arr.length; ++i) {
if (/_MANAGER$/.test(arr[i])) {
managers.push(arr[i].replace(/_.*$/, ""));
}
else {
employees.push(arr[i].replace(/_.*$/, ""));
}
}
for (var i=0; i < all.length; ++i) {
if (managers.includes(all[i]) && employees.includes(all[i])) {
console.log("Person " + all[i] + " is both a manager and an employee.");
}
else {
var type = managers.includes(all[i]) ? "manager" : "employee";
console.log("Person " + all[i] + " is a " + type + " only.");
}
}
Note that ideally you should also maintain a separate list/array of all people.
You can simply do this with regex but also passing the actual array to compare values. Currently you are just matching the current item in both times and not the current and succeeding one.
You can do something like
let arr =['A_MANAGER','B_MANAGER','C_MANAGER','A_EMPLOYEE','C_EMPLOYEE']
arr.map((total,key,arr)=>{
if(arr[key+1] != undefined){
return !(new RegExp(/EMPLOYEE/).test(total) && new RegExp(/EMPLOYEE/).test(arr[key+1]));
}
//Output : True,True,True,False
You can check the working example here
https://www.w3schools.com/code/tryit.asp?filename=GS103YAMF97P
I am checking that a particular value of an array is exist in a string or not. For that I had implemented the following code
function Check() {
var Value = 'I III';
var Opt = new Array("I", "II", "III", "IV");
for (var i = 0; i < Opt.length; i++) {
if (Value.indexOf(Opt[i]) > -1) {
alert("Hello");
}
}
}
if value exists in string it should display an alert, but the problem is that it display the alert 3 times instead of 2 times, because indexOf is assuming II as a part of string because III exists in string.
The easiest way to work around this would be to split Value with a delimiter (e.g., at each space) with String.prototype.split:
var value = 'I III'.split(' ')
var options = ['I', 'II', 'III', 'IV']
options.forEach(function(option) {
var index = value.indexOf(option)
if (index !== -1) {
// don't use `document.write` in general; it's just very useful in stack snippets
document.write(index + ' : ' + value[index])
document.write('<br>')
}
})
A couple notes:
don't capitalize your variable names; use camelCase for variables and PascalCase for classes/etc
don't use new Array(); instead prefer the array literal: []
This is the another way to get the ans
function Check() {
var Value = 'I III'.split(" "); var Opt = ["I", "II", "III", "IV"];
for (var i = 0; i < Opt.length; i++) {
if (Value.indexOf(Opt[i]) > -1) {
alert("Hello");
}
}
}Check();
I got this string:
var longText="This is a superuser test, super user is is super important!";
I want to know how many times the string "su" is in longText and the position of each "su".
I was trying with:
var nr4 = longText.replace("su", "").length;
And the difference of lenght between the main text and the nr4 divided by "su" lenght beeing 2 is resulting a number of repetitions but i bet there is a better way of doing it.
For example
var parts=longText.split("su");
alert(parts.length-1); // length will be two if there is one "su"
More details using exec
FIDDLE
var re =/su/g, pos=[];
while ((result = re.exec(longText)) !== null) {
pos.push(result.index);
}
if (pos.length>0) alert(pos.length+" found at "+pos.join(","));
Use exec. Example amended from the MDN code. len contains the number of times su appears.
var myRe = /su/g;
var str = "This is a superuser test, super user is is super important!";
var myArray, len = 0;
while ((myArray = myRe.exec(str)) !== null) {
len++;
var msg = "Found " + myArray[0] + ". ";
msg += "Next match starts at " + myRe.lastIndex;
console.log(msg, len);
}
// "Found su. Next match starts at 12" 1
// "Found su. Next match starts at 28" 2
// "Found su. Next match starts at 45" 3
DEMO
Could do :
var indexesOf = function(baseString, strToMatch){
var baseStr = new String(baseString);
var wordLen = strToMatch.length;
var listSu = [];
// Number of strToMatch occurences
var nb = baseStr.split(strToMatch).length - 1;
for (var i = 0, len = nb; i < len; i++){
var ioF = baseStr.indexOf(strToMatch);
baseStr = baseStr.slice(ioF + wordLen, baseStr.length);
if (i > 0){
ioF = ioF + listSu[i-1] + wordLen;
}
listSu.push(ioF);
}
return listSu;
}
indexesOf("This is a superuser test, super user is is super important!","su");
return [10, 26, 43]
var longText="This is a superuser test, super user is is super important!";
var count = 0;
while(longText.indexOf("su") != -1) { // NB the indexOf() method is case sensitive!
longText = longText.replace("su",""); //replace first occurence of 'su' with a void string
count++;
}
I'm currently implementing a substring search. From the algorithm, I get array of substrings occurence positions where each element is in the form of [startPos, endPos].
For example (in javascript array):
[[1,3], [8,10], [15,18]]
And the string to highlight is:
ACGATCGATCGGATCGAGCGATCGAGCGATCGAT
I want to highlight (in HTML using <b>) the original string, so it will highlight or bold the string from position 1 to 3, then 8 to 10, then 15 to 18, etc (0-indexed).
A<b>CGA</b>TCGA<b>TCG</b>GATC<b>GAGC</b>GATCGAGCGATCGAT
This is what I have tried (JavaScript):
function hilightAtPositions(text, posArray) {
var startPos, endPos;
var startTag = "<b>";
var endTag = "</b>";
var hilightedText = "";
for (var i = 0; i < posArray.length; i++) {
startPos = posArray[i][0];
endPos = posArray[i][1];
hilightedText = [text.slice(0, startPos), startTag, text.slice(startPos, endPos), endTag, text.slice(endPos)].join('');
}
return hilightedText;
}
But it highlights just a range from the posArray (and I know it is still incorrect yet). So, how can I highlight a string given multiple occurrences position?
Looking at this question, and following John3136's suggestion of going from tail to head, you could do:
String.prototype.splice = function( idx, rem, s ) {
return (this.slice(0,idx) + s + this.slice(idx + Math.abs(rem)));
};
function hilightAtPositions(text, posArray) {
var startPos, endPos;
posArray = posArray.sort(function(a,b){ return a[0] - b[0];});
for (var i = posArray.length-1; i >= 0; i--) {
startPos = posArray[i][0];
endPos = posArray[i][1];
text= text.splice(endPos, 0, "</b>");
text= text.splice(startPos, 0, "<b>");
}
return text;
}
Note that in your code, you are overwriting hilightedText with each iteration, losing your changes.
Try this:
var stringToHighlight = "ACGATCGATCGGATCGAGCGATCGAGCGATCGAT";
var highlightPositions = [[1,3], [8,10], [15,18]];
var lengthDelta = 0;
for (var highlight in highlightPositions) {
var start = highlightPositions[highlight][0] + lengthDelta;
var end = highlightPositions[highlight][1] + lengthDelta;
var first = stringToHighlight.substring(0, start);
var second = stringToHighlight.substring(start, end + 1);
var third = stringToHighlight.substring(end + 1);
stringToHighlight = first + "<b>" + second + "</b>" + third;
lengthDelta += ("<b></b>").length;
}
alert(stringToHighlight);
Demo: http://jsfiddle.net/kPkk3/
Assuming that you're trying to highlight search terms or something like that. Why not replace the term with the bolding?
example:
term: abc
var text = 'abcdefgabcqq';
var term = 'abc';
text.replace(term, '<b>' + term + '</b>');
This would allow you to avoid worrying about positions, assuming that you are trying to highlight a specific string.
Assuming your list of segments is ordered from lowest start to highest, try doing your array from last to first.
That way you are not changing parts of the string you haven't reached yet.
Just change the loop to:
for (var i = posArray.length-1; i >=0; i--) {
If you want to check for multiple string matches and highlight them, this code snippet works.
function highlightMatch(text, matchString) {
let textArr = text.split(' ');
let returnArr = [];
for(let i=0; i<textArr.length; i++) {
let subStrMatch = textArr[i].toLowerCase().indexOf(matchString.toLowerCase());
if(subStrMatch !== -1) {
let subStr = textArr[i].split('');
let subStrReturn = [];
for(let j=0 ;j<subStr.length; j++) {
if(j === subStrMatch) {
subStrReturn.push('<strong>' + subStr[j]);
} else if (j === subStrMatch + (matchString.length-1)){
subStrReturn.push(subStr[j] + '<strong>');
} else {
subStrReturn.push(subStr[j]);
}
}
returnArr.push(subStrReturn.join(''));
} else {
returnArr.push(textArr[i]);
}
}
return returnArr;
}
highlightMatch('Multi Test returns multiple results', 'multi');
=> (5) ['<strong>Multi<strong>', 'Test', 'returns', '<strong>multi<strong>ple', 'results']
Lets Say I have a list like
Dog
dOg
God
doggy
dogg
Zebra
Wood
What I want to do is find all the words in the list regardless of case, or regardless of the actual word. I want to match the letters and take a count. So from above
Dog, dOg, God would all be a match and in this case would return "3" as the count, but doggy, dogg, zebra, wood.. would all be unique and all would return 1 as the count.. Though I know this is possible I don't know where to begin. The anagram concept throws me off a bit. Any ideas?
var words = new Array("Dog", "dOg", "God", "doggy", "dogg","Zebra", "Wood");
var unique = {};
// iterate over all the words
for (i=0; i < words.length; i++) {
// get the word, all lowercase
var word = words[i].toLowerCase();
// sort the word's letters
word = word.split('').sort().join('')
// keep a count of unique combinations
if(unique[word])
unique[word] += 1;
else
unique[word] = 1;
}
// print the histogram
for (u in unique)
document.write(u + ": " + unique[u] + "<br/>")
here's what I came up with... jsfiddle here
$(document).ready(function() {
var mywords = ['Dog', 'dOg', 'God', 'doggy', 'dogg', 'Zebra', 'Wood'];
var finalArr = {};
for (var i = 0; i < mywords.length; i++) {
var temp = mywords[i].toLowerCase();
var letters = temp.split('');
var sorted = letters.sort();
var final = sorted.join("");
if(typeof finalArr[final] != 'undefined'){
finalArr[final] ++;
} else {
finalArr[final] = 1;
}
}
console.log(finalArr);
for(var i in finalArr) {
alert(i + ': ' + finalArr[i]);
document.write(i + ': ' + finalArr[i] + "<br/>");
}
});