I am trying to use replace with a while loop. I want to replace the first letter in the string with an empty string if the letters is not a vowel. The regex I have used is working because the letters are added to the end of the string, just not sure what is happening with the replace function?
Here is my code:
vowel = new RegExp("[aeiou]");
word = "cherry";
var moved = '',
i = 0;
while (!vowel.test(word[i])) {
moved += word[i];
word.replace(word[i], '');
i++;
}
return word+moved;
For example, 'cherrych' will be returned rather than 'errych'
You don't need a loop here, just use standard regex multiple selectors, e.g. see the following:
'cherrych'.replace(/^[^aeiou]*/, '')
String.prototype.replace returns a modified copy of the string, and does not alter the string in place.
Every time you do word.replace(), you cause a new string to be returned but importantly word is not altered at all.
The right way to attack this is then to assign this new modified copy to the original by
word = word.replace(word[i],'');
Related
let str = 'axybexaseraszarasxar';
i want string between "a" to next "a" like 'axybexa' string is there any way to take it using substring or slice function of string
You need firstly to detect where the beginning and the end of the substring you want are.
let str = 'axybexaseraszarasxar';
const strBetweenMatches = (st,sep) => {
const first = st.indexOf(sep);
const second = st.indexOf(sep,first+1);
if (second < first) return st.slice(first);
return st.slice(first,second+1)
}
console.log(strBetweenMatches(str,'a')); // your desired output
console.log(strBetweenMatches(str,'j')); // no match
console.log(strBetweenMatches(str,'z')); // only one match
If you want the substring, you can do like this:
let str = 'axybexaseraszarasxar';
let subtring = str.slice(str.indexOf("axybexa") , 7)
If you want to get the new string after slicing off the substring:
let str = 'axybexaseraszarasxar';
let new_string = str.slice(7 , str.length)
It depends on the behaviour that you want.
But one way to do it would be to combine the search() method and the substring() method to clear your specific example.
str.substring(str.search(wordToFind),lengthOfWord);
However, if you want to build it more dynamically there should be some sort of indication as to why you want that specific word. If you always receive it, why even try and break it out of the string?
As an example, IF the search() method doesn't find the word, a -1 will be returned which means you can always check if it exists within the string and if it does, always use it as a separate variable.
Another inefficient way to do it would be to use a for loop and go through each letter in the string individually until you find a succession of the letters you're looking for.
Using the answer from:
split string in two on given index and return both parts
You can always create a split function that allows you to always break up the string on a specific index.
--------------------------------------------------------------
Since the question was just changed, Malarres' answer is the one you want. Use indexOf to find the beginning and end of the substring you're after.
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.
There is a part in my string from, to which I would like to replace to an another string replace_string. My code should work, but what if there is an another part like the returned substring?
var from=10, to=17;
//...
str = str.replace(str.substring(from, to), replace_string);
For example:
from=4,to=6
str = "abceabxy"
replace_string = "zz"
the str should be "abcezzxy"
What you want to do is simple! Cut out and replace the string. Here is the basic tool, you need scissor and glue! Oops I mean string.Split() and string.Replace().
How to use?
Well I am not sure if you want to use string.Split() but you have used string.Replace() so here goes.
String.Replace uses two parameters, like this ("one", "two") what you need to make sure is that you are not replacing a char with a string or a string with a char. They are used as:
var str="Visit Microsoft!";
var n=str.replace("Microsoft","W3Schools");
Your code:
var from=10, to=17;
//...
var stringGot = str.replace(str.substring(from, to), replace_string);
What you should do will be to split the code first, and then replace the second a letter! As you want one in your example. Thats one way!
First, split the string! And then replaced the second a letter with z.
For String.Replace refer this: http://www.w3schools.com/jsref/jsref_replace.asp
For String.SubString: http://www.w3schools.com/jsref/jsref_substring.asp
For String.Split: http://www.w3schools.com/jsref/jsref_split.asp
Strings are immutable. This means they do not change after they are first instantiated. Every method to manipulate a string actually returns a new instance of a string. So you have to assign your result back to the variable like this:
str = str.replace(str.substring(from, to), replace_string);
Update: However, the more efficient way of doing this in the first place would be the following. it is also less prone to errors:
str = str.substring(0, from) + replace_string + str.substring(to);
See this fiddle: http://jsfiddle.net/cFtKL/
It runs both of the commands through a loop 100,000 times. The first takes about 75ms whereas the latter takes 20ms.
I am writing a little app for Sharepoint. I am trying to extract some text from the middle of a field that is returned:
var ows_MetaInfo="1;#Subject:SW|NameOfADocument
vti_parservers:SR|23.0.0.6421
ContentTypeID:SW|0x0101001DB26Cf25E4F31488B7333256A77D2CA
vti_cachedtitle:SR|NameOfADocument
vti_title:SR|ATitleOfADocument
_Author:SW:|TheNameOfOurCompany
_Category:SW|
ContentType:SW|Document
vti_author::SR|mrwienerdog
_Comments:SW|This is very much the string I need extracted
vti_categories:VW|
vtiapprovallevel:SR|
vti_modifiedby:SR|mrwienerdog
vti_assignedto:SR|
Keywords:SW|Project Name
ContentType _Comments"
So......All I want returned is "This is very much the string I need extracted"
Do I need a regex and a string replace? How would you write the regex?
Yes, you can use a regular expression for this (this is the sort of thing they are good for). Assuming you always want the string after the pipe (|) on the line starting with "_Comments:SW|", here's how you can extract it:
var matchresult = ows_MetaInfo.match(/^_Comments:SW\|(.*)$/m);
var comment = (matchresult==null) ? "" : matchresult[1];
Note that the .match() method of the String object returns an array. The first (index 0) element will be the entire match (here, we the entire match is the whole line, as we anchored it with ^ and $; note that adding the "m" after the regex makes this a multiline regex, allowing us to match the start and end of any line within the multi-line input), and the rest of the array are the submatches that we capture using parenthesis. Above we've captured the part of the line that you want, so that will present in the second item in the array (index 1).
If there is no match ("_Comments:SW|" doesnt appear in ows_MetaInfo), then .match() will return null, which is why we test it before pulling out the comment.
If you need to adjust the regex for other scenarios, have a look at the Regex docs on Mozilla Dev Network: https://developer.mozilla.org/en/JavaScript/Guide/Regular_Expressions
You can use this code:
var match = ows_MetaInfo.match(/_Comments:SW\|([^\n]+)/);
if (match)
document.writeln(match[1]);
I'm far from competent with RegEx, so here is my RegEx-less solution. See comments for further detail.
var extractedText = ExtractText(ows_MetaInfo);
function ExtractText(arg) {
// Use the pipe delimiter to turn the string into an array
var aryValues = ows_MetaInfo.split("|");
// Find the portion of the array that contains "vti_categories:VW"
for (var i = 0; i < aryValues.length; i++) {
if (aryValues[i].search("vti_categories:VW") != -1)
return aryValues[i].replace("vti_categories:VW", "");
}
return null;
}
Here's a working fiddle to demonstrate.
I've got a problem with replace not working.
alert($('input#membership_edc').next("label").html().replace(/£/g, ""));
The value of the label after the input would be £24.00, but I want to do a math on that value then put it back with the new value. It's not removing the pound sign.
What's wrong? Thanks.
To read/modify/write use the function parameter version of .html():
$('input#membership_edc').next("label").html(function(index, old) {
var n = parseFloat(old.replace('£', '');
return n + 10;
});
would replace '£24.00' with '34'.
You need to set the value returned from the replace. Try below,
var $label = $('input#membership_edc').next("label");
$label.html($label.html().replace(/£/g, ""));
Nothing wrong. It is working here.
Are you sure your markup is fine?
The string replace function returns a new string. Strings themselves are immutable in javascript, I think. As Vega has it:
// avoid looking this up twice
var label = alert($('input#membership_edc').next("label");
// replace and assign
label.html(label.html().replace(/£/g, ""));
Edit:
To get the numerical value from the string:
var amount = alert($('input#membership_edc').next("label").html().match(/£\s*([-0-9.]+)/)[1];
This matches the numbers etc after the £ (ignoring whitespace), and uses index 1 from the array, containing the contents of the first group match (in the brackets).
" £1.45".match(/£\s*([-0-9.]+)/)[1]; // returns "1.45"
Beware that it is still a string, so you might want to do parseFloat on it.