JavaScript not removing text when a uppercase letter involved - javascript

So I have a text box on my website and I have coded this to prevent certain words from being used.
window.onload = function() {
var banned = ['MMM', 'XXX'];
document.getElementById('input_1_17').addEventListener('keyup', function(e) {
var text = document.getElementById('input_1_17').value;
for (var x = 0; x < banned.length; x++) {
if (text.toLowerCase().search(banned[x]) !== -1) {
alert(banned[x] + ' is not allowed!');
}
var regExp = new RegExp(banned[x]);
text = text.replace(regExp, '');
}
document.getElementById('input_1_17').value = text;
}, false);
}
The code works perfectly and removes the text from the text box when all the letters typed are lowercase. The problem is when the text contained an uppercase letter it will give the error but the word will not be removed from the text box.

The RegExp is a good direction, just you need some flags (to make it case-insensitive, and global - so replace all occurrences):
var text="Under the xxx\nUnder the XXx\nDarling it's MMM\nDown where it's mmM\nTake it from me";
console.log("Obscene:",text);
var banned=["XXX","MMM"];
banned.forEach(nastiness=>{
text=text.replace(new RegExp(nastiness,"gi"),"");
});
console.log("Okay:",text);

Normally you should use .toLowerCase() with both sides when comparing the strings so they can logically be matched.
But the problem actually comes from the Regex you are using, where you are ignoring case sensitivity, you just need to add the i flag to it:
var regExp = new RegExp(banned[x], 'gi');
text = text.replace(regExp, '');
Note:
Note also that using an alert() in a loop is not recommended, you can change your logic to alert all the matched items in only one alert().

You seem to have been expecting something unreasonable. Lowercase strings will never match strings containing uppercase letters.
Either convert both for comparison or use lowercase banned strings. The former would be more reliable, taking future human error out of the process.

What you can do is actually convert both variables to either all caps or all lowercase.
if (text.toLowerCase().includes(banned[x].toLowerCase())) {
alert(banned[x] + ' is not allowed!');
}
Not tested but it should work. No need to use search since you don't need the index anyway. using includes is cleaner. includes docs

Related

Uppercase for each new word swedish characters and html markup

I was pointed out to this post, which does not seem to follow the criteria I have:
Replace a Regex capture group with uppercase in Javascript
I am trying to make a regex that will:
format a string by adding uppercase for the first letter of each word and lower case for the rest of the characters
ignore HTML markup
Accept swedish characters (åäöÅÄÖ)
Say I've got this string:
<b>app</b>le store östersund
Then I want it to be (changes marked by uppercase characters)
<b>App</b>le Store Östersund
I've been playing around with it and the closest I've got is the following:
(?!([^<])*?>)[åäöÅÄÖ]|\s\b\w
Resulted in
<b>app</b>le Store Östersund
Or this
/(?!([^<])*?>)[åäöÅÄÖ]|\S\b\w/g
Resulted in
<B>App</B>Le store Östersund
Here's a fiddle:
http://refiddle.com/refiddles/598aabef75622d4a531b0000
Any help or advice is much appreciated.
It is not possible to do this with regexp alone, since regexp doesn't understand HTML structure. [*] Instead, we need to process each text node, and carry through our logic for what is the beginning of the word in case a word continues across different text nodes. A character is at start of the word if it is preceded by a whitespace, or if it is at the start of the string and it is either the first text node, or the previous text node ended in whitespace.
function htmlToTitlecase(html, letters) {
let div = document.createElement('div');
let re = new RegExp("(^|\\s)([" + letters + "])", "gi");
div.innerHTML = html;
let treeWalker = document.createTreeWalker(div, NodeFilter.SHOW_TEXT);
let startOfWord = true;
while (treeWalker.nextNode()) {
let node = treeWalker.currentNode;
node.data = node.data.replace(re, function(match, space, letter) {
if (space || startOfWord) {
return space + letter.toUpperCase();
} else {
return match;
}
});
startOfWord = node.data.match(/\s$/);
}
return div.innerHTML;
}
console.log(htmlToTitlecase("<b>app</b>le store östersund", "a-zåäö"));
// <b>App</b>le Store Östersund
[*] Maybe possible, but even if so, it would be horribly ugly, since it would need to cover an awful amount of corner cases. Also might need a stronger RegExp engine than JavaScript's, like Ruby's or Perl's.
EDIT:
Even if just specifying really simple html tags? The only ones I am actually in need of covering is <b> and </b> at the moment.
This was not specified in the question. The solution is general enough to work for any markup (including simple tags). But...
function simpleHtmlToTitlecaseSwedish(html) {
return html.replace(/(^|\s)(<\/?b>|)([a-zåäö])/gi, function(match, space, tag, letter) {
return space + tag + letter.toUpperCase();
});
}
console.log(simpleHtmlToTitlecaseSwedish("<b>app</b>le store östersund", "a-zåäö"));
I have a solution which use almost only regex. It may be not the most intuitive way to do it, but it should be effective and I find it funny :)
You have to append at the end of your string every lowercase character followed by their uppercase counterpart, like this (it must also be preceded by a space for my regex) :
aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZåÅäÄöÖ
(I don't know which letters are missing, I know nothing about swedish alphabet, sorry... I'm counting on you to correct that !)
Then you can use the following regex :
(?![^<]*>)(\s<[^/]*?>|\s|^)([\wåäö])(?=.*\2(.)\S*$)|[\wåÅäÄöÖ]+$
Replace by :
$1$3
Test it here
Here is a working javascript code :
// Initialization
var regex = /(?![^<]*>)(\s<[^/]*?>|\s|^)([\wåäö])(?=.*\2(.)\S*$)|[\wåÅäÄöÖ]+$/g;
var string = "test <b when=\"2>1\">ap<i>p</i></b>le store östersund";
// Processing
result = string + " aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZåÅäÄöÖ";
result = result.replace(regex, "$1$3");
// Display result
console.log(result);
Edit : I forgot to handle first word of the string, it's corrected :)

ASCII character not being recognized in if statement

I am trying to get a string from a html page with jquery and this is what I have.
var text = $(this).text();
var key = text.substring(0,1);
if(key == ' ' || key == ' ')
key = text.substring(1,2);
text is this  Home
And I want to skip the space and or the keycode above It appears this code does not work either. It only gets the text.substring(0,1); instead of text.substring(1,2); because the if statement is not catching.= and I am not sure why. Any help would be super awesome! Thanks!
There are several problems with the code in the question. First,   has no special meaning in JavaScript: it is a string literal with six characters. Second, text.substring(1,2) returns simply the second character of text, not all characters from the second one onwards.
Assuming that you wish to remove one leading SPACE or NO-BREAK SPACE (which is what   means in HTML; it is not an Ascii character, by the way), then the following code would work:
var first = text.substring(0, 1);
if(first === ' ' || first === '\u00A0') {
text = text.substring(1, text.length);
}
The notation \u00A0 is a JavaScript escape notation for NO-BREAK SPACE U+00A0.
Should you wish to remove multiple spaces at the start, and perhaps at the end too, some modifications are needed. In that case, using a replace operation with regular expression is probably best.
If you want remove spaces at the beginning (and end) of a string, you can use the trim function
var myvar = " home"
myVar.trim() // --> "home"
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim

Javascript/Jquery - how to replace a word but only when not part of another word?

I am currently doing a regex comparison to remove words (rude words) from a text field when written by the user. At the moment it performs the check when the user hits space and removes the word if matches. However it will remove the word even if it is part of another word. So if you type apple followed by space it will be removed, that's ok. But if you type applepie followed by space it will remove 'apple' and leave pie, that's not ok. I am trying to make it so that in this instance if apple is part of another word it will not be removed.
Is there any way I can perform the comparison on the whole word only or ignore the comparison if it is combined with other characters?
I know that this allows people to write many rude things with no space. But that is the desired effect by the people that give me orders :(
Thanks for any help.
function rude(string) {
var regex = /apple|pear|orange|banana/ig;
//exaple words because I'm sure you don't need to read profanity
var updatedString = string.replace( regex, function(s) {
var blank = "";
return blank;
});
return updatedString;
}
$(input).keyup(function(event) {
var text;
if (event.keyCode == 32) {
var text = rude($(this).val());
$(this).val(text);
$("someText").html(text);
}
}
You can use word boundaries (\b), which match 0 characters, but only at the beginning or end of a word. I'm also using grouping (the parentheses), so it's easier to read an write such expressions.
var regex = /\b(apple|pear|orange|banana)\b/ig;
BTW, in your example you don't need to use a function. This is sufficient:
function rude(string) {
var regex = /\b(apple|pear|orange|banana)\b/ig;
return string.replace(regex, '');
}

Matching hashes using regex, but not when they are part of an url

I am struggling with a regex in javascript that needs the text after # to the first word boundary, but not match it if it is part of an url. So
#test - should match test
sometext#test2 - should match test2
xx moretext#test3 - should match test3
http://test.com#tab1 - should not match tab1
I am replacing the text after the hash with a link (but not the hash character itself). There can be more than one hash in the text, and it should match them all (I guess I should use /g for that).
Matching the part after the hash is quite easy: /#\b(.+?)\b/g, but not matching it if the string itself starts with "http" is something I cannot solve. I should probably use a negative look-around, but I am having problems getting my head around that.
Any help is greatly appreciated!
Try this regex using a negative lookahead instead since JS doesn't support lookbehinds:
/^(?!http:\/\/).*#\b(.+?)\b/
You may want to check for www too, depending on your conditions.
Edit: Then you can do this:
str = str.replace(re.exec(str)[1], 'replaced!');
http://jsfiddle.net/j7c79/2/
Edit 2: Sometimes a regex alone is not the way to go if it gets too complicated. Try a different approach:
var txt = "asdfgh http://asdf#test1 #test2 woot#test3";
function replaceHashWords(str, rep) {
var isUrl = /^http/.test(str), result = [];
!isUrl && str.replace(/#\b(.+?)\b/g, function(a,b){ result.push(b); });
return str.replace((new RegExp('('+ result.join('|') +')','g')), rep);
}
alert(replaceHashWords(txt, 'replaced!'));
// asdfgh http://asdf#replaced! #replaced! woot#replaced!
As regex is, often (if not always), quite expensive to use, I'd suggest using basic string, and array, methods to determine whether a given set of characters represents an URL (though I'm assuming that all URLS will start with the http string):
$('ul li').each(
function() {
var t = $(this).text(),
words = t.split(/\s+/),
foundHashes = [],
word = '';
for (var i = 0, len = words.length; i < len; i++) {
word = words[i];
if (word.indexOf('http') == -1 && word.indexOf('#') !== -1) {
var match = word.substring(word.indexOf('#') + 1);
foundHashes.push(match);
}
}
// the following just shows what, if anything, was found
// and can definitely be safely omitted
if (foundHashes.length) {
var newSpan = $('<span />', {
'class': 'matchedWords'
}).text(foundHashes.join(', ')).appendTo($(this));
}
});
JS Fiddle demo (with some timing information printed to the console).
References:
jQuery:
appendTo().
each().
text().
'Vanilla' JavaScript
Array.join().
String.indexOf().
String.split().
String.substring().
This would require a lookbehind, something sadly lacking from JavaScript's capabilities.
However, if your subject string is some HTML and those URLs are in href attributes, you can create a document out of it and search for text nodes, only replacing their nodeValues instead of the whole HTML string.

How to replace whitespaces using javascript?

I'm trying to remove the whitespaces from a textarea . The below code is not appending the text i'm selecting from two dropdowns. Can somebody tell me where i'd gone wrong? I'm trying to remove multiple spaces within the string as well, will that work with the same? Dont know regular expressions much. Please help.
function addToExpressionPreview() {
var reqColumnName = $('#ddlColumnNames')[0].value;
var reqOperator = $('#ddOperator')[0].value;
var expressionTextArea = document.getElementById("expressionPreview");
var txt = document.createTextNode(reqColumnName + reqOperator.toString());
if (expressionTextArea.value.match(/^\s+$/) != null)
{
expressionTextArea.value = (expressionTextArea.value.replace(/^\W+/, '')).replace(/\W+$/, '');
}
expressionTextArea.appendChild(txt);
}
> function addToExpressionPreview() {
> var reqColumnName = $('#ddlColumnNames')[0].value;
> var reqOperator = $('#ddOperator')[0].value;
You might as well use document.getElementById() for each of the above.
> var expressionTextArea = document.getElementById("expressionPreview");
> var txt = document.createTextNode(reqColumnName + reqOperator.toString());
reqOperator is already a string, and in any case, the use of the + operator will coerce it to String unless all expressions or identifiers involved are Numbers.
> if (expressionTextArea.value.match(/^\s+$/) != null) {
There is no need for match here. I seems like you are trying to see if the value is all whitespace, so you can use:
if (/^\s*$/.test(expressionTextArea.value)) {
// value is empty or all whitespace
Since you re-use expressionTextArea.value several times, it would be much more convenient to store it an a variable, preferably with a short name.
> expressionTextArea.value = (expressionTextArea.value.replace(/^\W+/,
> '')).replace(/\W+$/, '');
That will replace one or more non-word characters at the end of the string with nothing. If you want to replace multiple white space characters anywhere in the string with one, then (note wrapping for posting here):
expressionTextArea.value = expressionTextArea.value.
replace(/^\s+/,'').
replace(/\s+$/, '').
replace(/\s+/g,' ');
Note that \s does not match the same range of 'whitespace' characters in all browsers. However, for simple use for form element values it is probably sufficient.
Whitespace is matched by \s, so
expressionTextArea.value.replace(/\s/g, "");
should do the trick for you.
In your sample, ^\W+ will only match leading characters that are not a word character, and ^\s+$ will only match if the entire string is whitespace. To do a global replace(not just the first match) you need to use the g modifier.
Refer this link, you can get some idea. Try .replace(/ /g,"UrReplacement");
Edit: or .split(' ').join('UrReplacement') if you have an aversion to REs

Categories

Resources