If condition that pushes values that contain/match a string - javascript

I have a nicely functioning full calendar script. I have some filters for it, which basically have the following form:
$("input[name='event_filter_select']:checked").each(function () {
// I specified data-type attribute in HTML checkboxes to differentiate
// between risks and tags.
// Saving each type separately
if ($(this).data('type') == 'risk') {
risks.push($(this).val());
} else if ($(this).data('type') == 'tag') {
tagss.push($(this).val());
}
});
However the else if statement should check if the checked value 'tag' is contained within the result set, not be the only value of the result set (as implied by the ==).
Now I can only filter results that have the checked tag-value only. But i want to filter those, which have the tag-value amongst many others.
I figure this is to be done with match(/'tag'/) but i cannot figure out for the life of me how to put that into an if-statement.
Would be really glad if someone could lead me in the right direction.

I would simply do:
...
if ($(this).data('type') == 'risk') {
risks.push($(this).val());
} else if ($(this).data('type').test(/^tag/) {
tagss.push($(this).val());
}
...
This works if the 'tag' must be at the beginning of the string.
If the 'tag' can be everywhere in the string, you can use test(/tag/).

If your data is a string, example: tag filter1 filter2 filter3, you could use the indexOf-function (manual)
Code:
if ($(this).data('type').indexOf("risk") != -1))
//Action here.
indexOf returns -1 if the text isn't found.

You can use:
var re = new RegExp('\\b' + word + '\\b', 'i');
or if you wish to have the word hard-coded in (e.g., in the example, the word test):
var re = /\btest\b/i
Example showing the matches below:
var input = document.querySelector('input');
var div = document.querySelector('div');
var re;
var match;
input.addEventListener('keyup', function() {
match = input.value.trim();
re = new RegExp('\\b' + match + '\\b', 'i');
if($('div').data('type').match(re))
div.innerHTML = 'Matched the word: ' + '<strong>' + match + '</strong>';
else div.innerHTML = 'Did not match the word: ' + '<strong>' + match + '</strong>';
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Word to match:<input></input><br>
Output:
<div data-type='tag tags test'></div>
With the above regular expression incorporated into your code, it should look something like this:
else if ($(this).data('type').match(/\btag\b/i) { //true for data-type that has `tag` in it.
tagss.push($(this).val());
}

Try with this condition.
/\btag\b/.test($(this).data('type'))

Related

Recombine capture groups in single regexp?

I am trying to handle input groups similar to:
'...A.B.' and want to output '.....AB'.
Another example:
'.C..Z..B.' ==> '......CZB'
I have been working with the following:
'...A.B.'.replace(/(\.*)([A-Z]*)/g, "$1")
returns:
"....."
and
'...A.B.'.replace(/(\.*)([A-Z]*)/g, "$2")
returns:
"AB"
but
'...A.B.'.replace(/(\.*)([A-Z]*)/g, "$1$2")
returns
"...A.B."
Is there a way to return
"....AB"
with a single regexp?
I have only been able to accomplish this with:
'...A.B.'.replace(/(\.*)([A-Z]*)/g, "$1") + '...A.B.'.replace(/(\.*)([A-Z]*)/g, "$2")
==> ".....AB"
If the goal is to move all of the . to the beginning and all of the A-Z to the end, then I believe the answer to
with a single regexp?
is "no."
Separately, I don't think there's a simpler, more efficient way than two replace calls — but not the two you've shown. Instead:
var str = "...A..B...C.";
var result = str.replace(/[A-Z]/g, "") + str.replace(/\./g, "");
console.log(result);
(I don't know what you want to do with non-., non-A-Z characters, so I've ignored them.)
If you really want to do it with a single call to replace (e.g., a single pass through the string matters), you can, but I'm fairly sure you'd have to use the function callback and state variables:
var str = "...A..B...C.";
var dots = "";
var nondots = "";
var result = str.replace(/\.|[A-Z]|$/g, function(m) {
if (!m) {
// Matched the end of input; return the
// strings we've been building up
return dots + nondots;
}
// Matched a dot or letter, add to relevant
// string and return nothing
if (m === ".") {
dots += m;
} else {
nondots += m;
}
return "";
});
console.log(result);
That is, of course, incredibly ugly. :-)

Regex match all strings containing a given series of letters or digits

I have a search box and i need to grab the value of this search and match all DIV which data-* value is starting with the search value.
Cases:
Search value: 201
Should match: data-year="2011", data-year="2012", data-year="2013"
Should fail: data-year="2009", data-year="2001"
This is what i come up with so far:
\\b(?=\\w*[" + token + "])\\w+\\b
token is a dynamic value from the search box. Therefore i need to use RegExp
This is working but it match all the value which contain 2 or 0 or 1 (for my understanding). so 2009 is valid match as well. :/
I also try to add the caret at the beginning in order to match the characthers just at the beginning of the world but clearly i'm missing something here:
^\\b(?=\\w*[" + token + "])\\w+\\b
The whole code is:
var token = '200'; // should fail
var tokenTwo = '201'; // shoudl work
var dataAtt = $('#div').data('year').toString();
var regexExpression ="^\\b(?=\\w*\\d*[" + token + "])\\w+\\d+\\b";
var regEXPRES = "^.*" + token + ".*$";
var regex = new RegExp(regexExpression, "i");
if( dataAtt.match(regex) ){
console.log(dataAtt);
alert('yey!!!');
} else {
alert('nope!! )')
}
and here is the JsFiddle http://jsfiddle.net/tk5m8coo/
p.s. I shouldn't have any cases where token is precede or follow by other characters, but if anyone as idea how to check also this, would be great. Just in case of any typo like s2015.
Problem is that you're putting your search value inside a character class when you enclose your regex by wrapping around [...].
You also don't need a lookahead. You can just use:
var regex = new RegExp("\\b\\w*" + value + "\\w*\\b");
To make sure search value is matched within a full word. (\w includes digits also so no need to use \d).
Full code:
var value = '20'; //token
var html = $("#div").html(); //data.()
var dataAtt = $('#div').data('year').toString();
var regex = new RegExp("\\b\\w*" + value + "\\w*\\b");
if( dataAtt.match(regex) ){
console.log(dataAtt + " matched");
} else {
console.log('nope')
}
Updated JS Fiddle
Or you can use indexOf():
var value = '20';
var html = $("#div").html();
var dataAtt = $('#div').data('year').toString();
if( dataAtt.indexOf(value) >= 0 ){
console.log('yey!!!');
} else {
console.log('nein!! )')
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id ="div" data-year="2015">
what bozo where 2015
</div>
Your regex is using a character class which will match any of the characters inside the square brackets. Remove the square brackets:
^\\b(?=\\w*" + token + ".*)\\w+\\b

Remove all html tags from string by list, except the first one

I have string of html tags and a list of forbidden tags:
Any tag that is found in forbiddenTags should be removed from str, except the first one.
Maybe it can be done by one loop of the string
I tried the next thing:
var forbiddenTags = ["div", "city"];
var str = '<?xml version="1.0" encoding="UTF-8"?>' +
'<ADDUMP>' +
' <HEADER>' +
' <div></div>' +
' <div>Help Wanted Line</div>' +
' </HEADER>' +
' <ADINFO>' +
' <CUSTOMER>' +
' <CITY></CITY>' +
' <Div></DIV>' +
' <STATE></STATE>' +
' </CUSTOMER>' +
' </ADINFO>' +
'</ADDUMP>' +
'</xml>';
var arrayLength = forbiddenTags.length;
for (var i = 0; i < arrayLength; i++) {
// remove all forbiddenTags (upper and lower case)
var re = new RegExp("</? *" + forbiddenTags[i] + "[^>]*>","gi");
str = str.replace(re, "");
}
console.log(str);
Unfortunately, there are two problems:
1) It removes also the first tag of the string that is found in forbiddenTags.
2) It doesn't remove the content of the tags.
example:
<div>hi</div>
<div>how</div>
<div></div>
should be:
<div>hi</div>
This is my jsfiddle:
http://jsfiddle.net/Ht6Ym/3469/
Any help appreciated!
To match the content of the tag as well as the tag itself, you need to change your regex to look for both the opening and closing tag at the same time. Currently, it only checks for one or the other, which is why the tag content is being left.
This regex looks for an opening tag (and any associated attributes) the matching closing tag, and any intervening text:
new RegExp("<(" + forbiddenTags[i] + ")[^>]*>(.*?)</\\1>", "gi")
Your other issue (not wanting to remove the first match) can be solved by passing an anonymous function as a parameter to str.replace. In that function, make use of a counter variable to determine when to remove a match.
To do that, you'll need to add a counter variable somewhere. If you want to leave the first match of each type of forbidden tag, put it inside your for loop. If you only want to keep the first forbidden tag found overall, initialize it outside your for loop (it's unclear which you want from your question). Then replace str = str.replace(re, ""); with this:
str = str.replace(re, function(matchedText){
if (++counter>1){
return "";
} else {
return matchedText;
}
});
This function runs against every match. If it's the first match, it simply returns that match (in effect, leaving it alone). Otherwise, it removes it.
Now, all together this makes your loop look like this:
for (var i = 0; i < forbiddenTags.length; i++) {
var counter=0
var re = new RegExp("<(" + forbiddenTags[i] + ")[^>]*>(.*?)</\\1>", "gi");
str = str.replace(re, function(matchedText){
if (++counter>1){
return "";
} else {
return matchedText;
}
});
}
If using jQuery is an option, you can make things look a bit cleaner (namely, removing that obnoxious regex) using the function found in this answer:
var removeElements = function(text, selector) {
var wrapped = $("<div>" + text + "</div>");
wrapped.find(selector+":not(:first)").remove();
return wrapped.html();
}
for (var i = 0; i < forbiddenTags.length; i++) {
str = removeElements(str, forbiddenTags[i]);
}
Use str.match to get all matches and discard all except for the first one.
It seems like the answer by Rob W on this post is what you are looking for.
All you need to change is the first = true to first = {} and check
if (!first[tag]) {
first[tag] = true;
} else {
return '';
}

javascript regex search start of every word and following word

I'm trying to write a regex based on user input that searches the start of every word and the following word (excluding the space) in a string. This is the current code i am using.
var ndl = 'needlehay', //user input
re = new RegExp('(?:^|\\s)' + ndl, 'gi'), //searches start of every word
haystack = 'needle haystack needle second instance';
re.test(haystack); //the regex i need should find 'needle haystack'
Any help or suggestions i'd gladly appreciate.
Thanks!
I'd iterate over the needle, and try each variation manually
function check(needle, haystack) {
if (haystack.replace(/\s/g, '').indexOf(needle) === 0) return true;
return needle.split('').some(function(char, i, arr) {
var m = (i===0 ? '' : ' ') + needle.slice(0,i) +' '+ needle.slice(i);
return haystack.indexOf(m) != -1;
});
}

JavaScript check if string contains any of the words from regex

I'm trying to check if a string contains any of these words:
AB|AG|AS|Ltd|KB|University
My current code:
var acceptedwords = '/AB|AG|AS|Ltd|KB|University/g'
var str = 'Hello AB';
var matchAccepted = str.match(acceptedwords);
console.log(matchAccepted);
if (matchAccepted !== null) { // Contains the accepted word
console.log("Contains accepted word: " + str);
} else {
console.log("Does not contain accepted word: " + str);
}
But for some strange reason this does not match.
Any ideas what I'm doing wrong?
That's not the right way to define a literal regular expression in Javascript.
Change
var acceptedwords = '/AB|AG|AS|Ltd|KB|University/g'
to
var acceptedwords = /AB|AG|AS|Ltd|KB|University/;
You might notice I removed the g flag : it's useless as you only want to know if there's one match, you don't want to get them all. You don't even have to use match here, you could use test :
var str = 'Hello AB';
if (/AB|AG|AS|Ltd|KB|University/.test(str)) { // Contains the accepted word
console.log("Contains accepted word: " + str);
} else {
console.log("Does not contain accepted word: " + str);
}
If you want to build a regex with strings, assuming none of them contains any special character, you could do
var words = ['AB','AG', ...
var regex = new RegExp(words.join('|'));
If your names may contain special characters, you'll have to use a function to escape them.
If you want your words to not be parts of other words (meaning you don't want to match "ABC") then you should check for words boundaries :
regex = new RegExp(words.map(function(w){ return '\\b'+w+'\\b' }).join('|'),'g');

Categories

Resources