I am doing some logic for the last word that is on the sentence. Words are separated by either space or with a '-' character.
What is easiest way to get it?
Edit
I could do it by traversing backwards from the end of the sentence, but I would like to find better way
Try splitting on a regex that matches spaces or hyphens and taking the last element:
var lastWord = function(o) {
return (""+o).replace(/[\s-]+$/,'').split(/[\s-]/).pop();
};
lastWord('This is a test.'); // => 'test.'
lastWord('Here is something to-do.'); // => 'do.'
As #alex points out, it's worth trimming any trailing whitespace or hyphens. Ensuring the argument is a string is a good idea too.
Using a regex:
/.*[\s-](\S+)/.exec(str)[1];
that also ignores white-space at the end
Have you tried the lastIndexOf function http://www.w3schools.com/jsref/jsref_lastIndexOf.asp
Or Split function http://www.w3schools.com/jsref/jsref_split.asp
Here is a similar discussion have a look
You can try something like this...
<script type="text/javascript">
var txt = "This is the sample sentence";
spl = txt.split(" ");
for(i = 0; i < spl.length; i++){
document.write("<br /> Element " + i + " = " + spl[i]);
}
</script>
Well, using Split Function
string lastWord = input.Split(' ').Last();
or
string[] parts = input.Split(' ');
string lastWord = parts[parts.Length - 1];
While this would work for this string, it might not work for a slightly different string, so either you'll have to figure out how to change the code accordingly, or post all the rules.
string input = ".... ,API";
here, the comma would be part of the "word".
Also, if the first method of obtaining the word is correct, ie. everything after the last space, and your string adheres to the following rules:
Will always contain at least one space
Does not end with one or more space (in case of this you can trim it)
then you can use this code that will allocate fewer objects on the heap for GC to worry about later:
string lastWord = input.Substring(input.LastIndexOf(' ') + 1);
I hope its help
Related
I'm new to regex and trying to figure out how to remove characters till the last - in the string. I currently have strings in the format like this:
purple-hoodie.jpg-1625739747918
I am trying to remove characters to essentially be left with:
-1625739747918
Does anyone have any advice on how to approach this? I'm struggling to work out how to indicate to reach the last - in the string, if that is even possible?
Thanks
Just use lastIndexOf
let str = 'purple-hoodie.jpg-1625739747918'
console.log(str.substring(str.lastIndexOf('-')))
I prefer a match approach here:
var input = "purple-hoodie.jpg-1625739747918";
var output = input.match(/-\d+$/)[0];
console.log("match is: " + output);
But this assumes that the input would end in all digits. A more general regex approach might use a replace all:
var input = "purple-hoodie.jpg-1625739747918";
var output = input.replace(/^.*(?=-)/, "");
console.log("match is: " + output);
Here is my solution.
const txt = 'purple-hoodie.jpg-1625739747918';
const result = txt.replace(/-\d+$/, '');
console.log(result)
This removes the last trailing digits prefixed by -.
I'm trying to create a function that removes all special characters (including periods) except apostrophes when they are naturally part of a word. The regex pattern I've made is supposed to remove anything that doesn't fit the schema of word either followed by an apostrophe ' and/or another word:
function removeSpecialCharacters(str) {
return str.toLowerCase().replace(/[^a-z?'?a-z ]/g, ``)
}
console.log(removeSpecialCharacters(`I'm a string.`))
console.log(removeSpecialCharacters(`I'm a string with random stuff.*/_- '`))
console.log(removeSpecialCharacters(`'''`))
As you can see from the snippet it works well except for removing the rogue apostrophes.
And if I add something like [\s'\s] or ['] to the pattern it breaks it completely. Why is it doing this and what am I missing here?
Alternate the pattern with '\B, which will match and remove apostrophes which are not followed by a word character, eg ab' or ab'#, while preserving strings like ab'c:
function removeSpecialCharacters(str) {
return str.toLowerCase().replace(/'\B|[^a-z'? ]/g, ``)
}
console.log(removeSpecialCharacters(`I'm a string.`))
console.log(removeSpecialCharacters(`I'm a string with random stuff.*/_- '`))
console.log(removeSpecialCharacters(`'''`))
(you can also remove the duplicated characters from the character set)
Not sure what went wrong with yours as I can't see what you attempted. However, I got this to work.
function removeSpecialCharacters(str) {
str = str.toLowerCase();
// reduce duplicate apostrophes to single
str = str.replace(/'+/g,`'`);
// get rid of wacky chars
str = str.replace(/[^a-z'\s]/g,'');
// replace dangling apostrophes
str = str.replace(/(^|\s)'(\s|$)/g, ``);
return str;
}
console.log(removeSpecialCharacters(`I'm a string.`))
console.log(removeSpecialCharacters(`I'm a string with random stuff.*/_- '`))
console.log(removeSpecialCharacters(`'''`))
console.log(removeSpecialCharacters(`regex 'til i die`))
Here's one very easy solution. To remove certain characteristics from a string, you can run a bunch of if-statements through a while loop. This allows you to chose exactly which symbols to remove.
while (increment < string.length)
{
if (string[increment] == "!")
}
delete "!";
}
increment += 1;
}
That's a simple rundown of what'll look like (not actual code) to give you a sense of what you're doing.
var name = "AlbERt EINstEiN";
function nameChanger(oldName) {
var finalName = oldName;
// Your code goes here!
finalName = oldName.toLowerCase();
finalName = finalName.replace(finalName.charAt(0), finalName.charAt(0).toUpperCase());
for(i = 0; i < finalName.length; i++) {
if (finalName.charAt(i) === " ")
finalName.replace(finalName.charAt(i+1), finalName.charAt(i+1).toUpperCase());
}
// Don't delete this line!
return finalName;
};
// Did your code work? The line below will tell you!
console.log(nameChanger(name));
My code as is, returns 'Albert einstein'. I'm wondering where I've gone wrong?
If I add in
console.log(finalName.charAt(i+1));
AFTER the if statement, and comment out the rest, it prints 'e', so it recognizes charAt(i+1) like it should... I just cannot get it to capitalize that first letter of the 2nd word.
There are two problems with your code sample. I'll go through them one-by-one.
Strings are immutable
This doesn't work the way you think it does:
finalName.replace(finalName.charAt(i+1), finalName.charAt(i+1).toUpperCase());
You need to change it to:
finalName = finalName.replace(finalName.charAt(i+1), finalName.charAt(i+1).toUpperCase());
In JavaScript, strings are immutable. This means that once a string is created, it can't be changed. That might sound strange since in your code, it seems like you are changing the string finalName throughout the loop with methods like replace().
But in reality, you aren't actually changing it! The replace() function takes an input string, does the replacement, and produces a new output string, since it isn't actually allowed to change the input string (immutability). So, tl;dr, if you don't capture the output of replace() by assigning it to a variable, the replaced string is lost.
Incidentally, it's okay to assign it back to the original variable name, which is why you can do finalName = finalName.replace(...).
Replace is greedy
The other problem you'll run into is when you use replace(), you'll be replacing all of the matching characters in the string, not just the ones at the position you are examining. This is because replace() is greedy - if you tell it to replace 'e' with 'E', it'll replace all of them!
What you need to do, essentially, is:
Find a space character (you've already done this)
Grab all of the string up to and including the space; this "side" of the string is good.
Convert the very next letter to uppercase, but only that letter.
Grab the rest of the string, past the letter you converted.
Put all three pieces together (beginning of string, capitalized letter, end of string).
The slice() method will do what you want:
if (finalName.charAt(i) === " ") {
// Get ONLY the letter after the space
var startLetter = finalName.slice(i+1, i+2);
// Concatenate the string up to the letter + the letter uppercased + the rest of the string
finalName = finalName.slice(0, i+1) + startLetter.toUpperCase() + finalName.slice(i+2);
}
Another option is regular expression (regex), which the other answers mentioned. This is probably a better option, since it's a lot cleaner. But, if you're learning programming for the first time, it's easier to understand this manual string work by writing the raw loops. Later you can mess with the efficient way to do it.
Working jsfiddle: http://jsfiddle.net/9dLw1Lfx/
Further reading:
Are JavaScript strings immutable? Do I need a "string builder" in JavaScript?
slice() method
You can simplify this down a lot if you pass a RegExp /pattern/flags and a function into str.replace instead of using substrings
function nameChanger(oldName) {
var lowerCase = oldName.toLowerCase(),
titleCase = lowerCase.replace(/\b./g, function ($0) {return $0.toUpperCase()});
return titleCase;
};
In this example I've applied the change to any character . after a word boundary \b, but you may want the more specific /(^| )./g
Another good answer to this question is to use RegEx to do this for you.
var re = /(\b[a-z](?!\s))/g;
var s = "fort collins, croton-on-hudson, harper's ferry, coeur d'alene, o'fallon";
s = s.replace(re, function(x){return x.toUpperCase();});
console.log(s); // "Fort Collins, Croton-On-Hudson, Harper's Ferry, Coeur D'Alene, O'Fallon"
The regular expression being used may need to be changed up slightly, but this should give you an idea of what you can do with regular expressions
Capitalize Letters with JavaScript
The problem is twofold:
1) You need to return a value for finalName.replace, as the method returns an element but doesn't alter the one on which it's predicated.
2) You're not iterating through the string values, so you're only changing the first word. Don't you want to change every word so it's in lower case capitalized?
This code would serve you better:
var name = "AlbERt EINstEiN";
function nameChanger(oldName) {
// Your code goes here!
var finalName = [];
oldName.toLowerCase().split(" ").forEach(function(word) {
newWord = word.replace(word.charAt(0), word.charAt(0).toUpperCase());
finalName.push(newWord);
});
// Don't delete this line!
return finalName.join(" ");
};
// Did your code work? The line below will tell you!
console.log(nameChanger(name));
if (finalName.charAt(i) === " ")
Shouldn't it be
if (finalName.charAt(i) == " ")
Doesn't === check if the object types are equal which should not be since one it a char and the other a string.
I'm trying to write the code so it removes the "bad" words from the string (the text).
The word is "bad" if it has comma or any special sign thereafter. The word is not "bad" if it contains only a to z (small letters).
So, the result I'm trying to achieve is:
<script>
String.prototype.azwords = function() {
return this.replace(/[^a-z]+/g, "0");
}
var res = "good Remove remove1 remove, ### rem0ve? RemoVE gooood remove.".azwords();//should be "good gooood"
//Remove has a capital letter
//remove1 has 1
//remove, has comma
//### has three #
//rem0ve? has 0 and ?
//RemoVE has R and V and E
//remove. has .
alert(res);//should alert "good gooood"
</script>
Try this:
return this.replace(/(^|\s+)[a-z]*[^a-z\s]\S*(?!\S)/g, "");
It tries to match a word (that is surrounded by whitespaces / string ends) and contains any (non-whitespace) character but at least one that is not a-z. However, this is quite complicated and unmaintainable. Maybe you should try a more functional approach:
return this.split(/\s+/).filter(function(word) {
return word && !/[^a-z]/.test(word);
}).join(" ");
okay, first off you probably want to use the word boundary escape \b in your regex. Also, it's a bit tricky if you match the bad words, because a bad word might contain lower case chars, so your current regex will exclude anything which does have lowecase letters.
I'd be tempted to pick out the good words and put them in a new string. It's a much easier regex.
/\b[a-z]+\b/g
NB: I'm not totally sure that it'll work for the first and last words in the string so you might need to account for that as well. http://www.regextester.com/ is exceptionally useful.
EDIT: as you want punctiation after the word to be 'bad', this will actually do what I was suggesting
(^|\s)[a-z]+(\s|$)
Firstly I wouldn't recommend changing the prototype of String (or of any native object) if you can avoid because you leave yourself open to conflicts with other code that might define the same property in different ways. Much better to put custom methods like this on a namespaced object, though I'm sure some will disagree.
Second, is there any need to use RegEx completely? (Genuine question; not trying to be facetious.)
Here is an example of the function with plain old JS using a little bit of RegEx here and there. Easier to comment, debug, and reuse.
Here is the code:
var azwords = function(str) {
var arr = str.split(/\s+/),
len = arr.length,
i = 0,
res = "";
for (i; i < len; i += 1) {
if (!(arr[i].match(/[^a-z]/))) {
res += (!res) ? arr[i] : " " + arr[i];
}
}
return res;
}
var res = "good Remove remove1 remove, ### rem0ve? RemoVE gooood remove."; //should be "good gooood"
//Remove has a capital letter
//remove1 has 1
//remove, has comma
//### has three #
//rem0ve? has 0 and ?
//RemoVE has R and V and E
//remove. has .
alert(azwords(res));//should alert "good gooood";
Try this one:
var res = "good Remove remove1 remove, ### rem0ve? RemoVE gooood remove.";
var new_one = res.replace(/\s*\w*[#A-Z0-9,.?\\xA1-\\xFF]\w*/g,'');
//Output `good gooood`
Description:
\s* # zero-or-more spaces
\w* # zero-or-more alphanumeric characters
[#A-Z0-9,.?\\xA1-\\xFF] # matches any list of characters
\w* # zero-or-more alphanumeric characters
/g - global (run over all string)
This will find all the words you want /^[a-z]+\s|\s[a-z]+$|\s[a-z]+\s/g so you could use match.
this.match(/^[a-z]+\s|\s[a-z]+$|\s[a-z]+\s/g).join(" "); should return the list of valid words.
Note that this took some time as a JSFiddle so it maybe more efficient to split and iterate your list.
I have strings with extra whitespace characters. Each time there's more than one whitespace, I'd like it be only one. How can I do this using JavaScript?
Something like this:
var s = " a b c ";
console.log(
s.replace(/\s+/g, ' ')
)
You can augment String to implement these behaviors as methods, as in:
String.prototype.killWhiteSpace = function() {
return this.replace(/\s/g, '');
};
String.prototype.reduceWhiteSpace = function() {
return this.replace(/\s+/g, ' ');
};
This now enables you to use the following elegant forms to produce the strings you want:
"Get rid of my whitespaces.".killWhiteSpace();
"Get rid of my extra whitespaces".reduceWhiteSpace();
Here's a non-regex solution (just for fun):
var s = ' a b word word. word, wordword word ';
// with ES5:
s = s.split(' ').filter(function(n){ return n != '' }).join(' ');
console.log(s); // "a b word word. word, wordword word"
// or ES2015:
s = s.split(' ').filter(n => n).join(' ');
console.log(s); // "a b word word. word, wordword word"
Can even substitute filter(n => n) with .filter(String)
It splits the string by whitespaces, remove them all empty array items from the array (the ones which were more than a single space), and joins all the words again into a string, with a single whitespace in between them.
using a regular expression with the replace function does the trick:
string.replace(/\s/g, "")
I presume you're looking to strip spaces from the beginning and/or end of the string (rather than removing all spaces?
If that's the case, you'll need a regex like this:
mystring = mystring.replace(/(^\s+|\s+$)/g,' ');
This will remove all spaces from the beginning or end of the string. If you only want to trim spaces from the end, then the regex would look like this instead:
mystring = mystring.replace(/\s+$/g,' ');
Hope that helps.
jQuery.trim() works well.
http://api.jquery.com/jQuery.trim/
I know I should not necromancy on a subject, but given the details of the question, I usually expand it to mean:
I want to replace multiple occurences of whitespace inside the string with a single space
...and... I do not want whitespaces in the beginnin or end of the string (trim)
For this, I use code like this (the parenthesis on the first regexp are there just in order to make the code a bit more readable ... regexps can be a pain unless you are familiar with them):
s = s.replace(/^(\s*)|(\s*)$/g, '').replace(/\s+/g, ' ');
The reason this works is that the methods on String-object return a string object on which you can invoke another method (just like jQuery & some other libraries). Much more compact way to code if you want to execute multiple methods on a single object in succession.
var x = " Test Test Test ".split(" ").join("");
alert(x);
Try this.
var string = " string 1";
string = string.trim().replace(/\s+/g, ' ');
the result will be
string 1
What happened here is that it will trim the outside spaces first using trim() then trim the inside spaces using .replace(/\s+/g, ' ').
How about this one?
"my test string \t\t with crazy stuff is cool ".replace(/\s{2,9999}|\t/g, ' ')
outputs "my test string with crazy stuff is cool "
This one gets rid of any tabs as well
If you want to restrict user to give blank space in the name just create a if statement and give the condition. like I did:
$j('#fragment_key').bind({
keypress: function(e){
var key = e.keyCode;
var character = String.fromCharCode(key);
if(character.match( /[' ']/)) {
alert("Blank space is not allowed in the Name");
return false;
}
}
});
create a JQuery function .
this is key press event.
Initialize a variable.
Give condition to match the character
show a alert message for your matched condition.