I am given a string as input, and the last letter in every word of the string should be capitalized, and then it is formed into their own div.
The one thing that I am finding tricky is that no matter what the string is there should always be enough divs to be separated, which to me means that I need to have a loop that generates it, which is what I am not sure how to write that logic.
I need this to be the output:
<div>
partY
</div>
<div>
likE
</div>
<div>
itS
</div>
<div>
2015
</div>
This is what I have so far:
function yay (input) {
input = input.toLowerCase().split("").reverse().join("").split(" ");
for(var i = 1 ; i < input.length ; i++){
var len = input[i].length-1;
input[i] = input[i].substring(0, len) + input[i].substr(len).toUpperCase();
}
return input .reverse().join(" ");
}
console.log(yay("Party like its 2015"));
Well, just a few minor changes to your code, which was on the right track... I basically removed the unnecessary reversing and wrapped each word in a div in the loop and viola:
function yay (input) {
input = input.toLowerCase().split(" ");
for(var i = 0 ; i < input.length ; i++){
var len = input[i].length-1;
input[i] = '<div>'+input[i].substring(0, len) + input[i].substr(len).toUpperCase()+'</div>';
}
return input.join("");
}
console.log(yay("Party like its 2015"));
document.write(yay("Party like its 2015"));
Output:
<div>partY</div><div>likE</div><div>itS</div><div>2015</div>
You can use document.createElement('div') and document.createTextNode('text') to simply get what you need.
You can return the content element directly to append to your node of your need, or you can use the innerHTML to do some text manipulations.
EDIT
Modified, I totally missed the last character needs to be uppercase
function yay(str) {
var arr = str.split(' ');
var content = document.createElement('div');
for(var part in arr) {
var sub = document.createElement('div');
var lastChar = arr[part].charAt(arr[part].length-1).toUpperCase();
var appendStr = arr[part].substring(0,arr[part].length-1);
sub.appendChild(document.createTextNode(appendStr+lastChar));
content.appendChild(sub);
}
return content.innerHTML;
}
console.log(yay("Party like its 2015"));
How about this:
function capitalizeLastLetter(input) {
return input.substring(0, input.length - 1) + input.charAt(input.length - 1).toUpperCase();
}
function yay(input) {
return input
.toLocaleLowerCase()
.split(" ")
.map(function(s){ return "<div>" + capitalizeLastLetter(s) + "</div>"; })
.join("");
}
console.log(yay("Party like its 2015"));
document.write(yay("Party like its 2015"));
Remixes this answer on how to capitalize the first letter of a word.
Add newlines where appropriate if you actually need those in your output.
You might want to use String.prototype.replace and feed it with a regular expression:
function yay(input) {
return input.
toLocaleLowerCase().
replace(/([^\s.,:;!?]*)([^\s.,:;!?")])([^\s]*)/g,
function(match, sub1, sub2, sub3) {
return '<div>' + sub1 + sub2.toLocaleUpperCase() + sub3 + '</div>';
});
}
The regex captures zero or more (because regular expressions are "greedy" by default, the algorithm will capture as many characters as it can) non-whitespace (to support alphabets other than Latin) and non-punctuation characters and exactly one non-whitespace/non-punctuation character following them (the last letter in the word, even if it's the only letter forming the word). The last group is zero or more of the previously specified punctuation marks (.,:;!?")). What it says is "non-whitespace character", but the presence of the two previous parenthesized groups implies that it must be a punctuation mark.
The replacement callback here uses four arguments, one (unused in this case) for the entire match and three for submatches corresponding to the parenthesized groups in the regex.
The value returned from the callback replaces the entire match in each successive replacement cycle (abcd in abcd efgh will be replaced with <div>abcD</div> and so on, note that whitespaces will be preserved).
In the callback function, the first submatch consists of all the letters in a word except the last one. It is returned as is, but the other match (which is the last letter) is capitalized. Optionally, a punctuation mark is appended if present in the original input. Everything is then wrapped in the <div> HTML tag and returned.
You can assign the value returned by the yay function to the innerHTML property of an HTML element, for example:
document.querySelector('#container').innerHTML = yay('Party like its 2015');
Spaces present in the input will remain. There is no need to replace them with new line characters, as all whitespaces are treated equally in HTML and will result in the same behavior.
Edit:
Now you can pass input containing punctuation to the function. The following line:
yay('Hello there, how about using some punctuation? "Quote" (Parentheses) ("What?")')
will result in:
'<div>hellO</div> <div>therE,</div> <div>hoW</div> <div>abouT</div> <div>usinG</div> <div>somE</div> <div>punctuatioN?</div> <div>"quotE"</div> <div>(parentheseS)</div> <div>("whaT?")</div>'
Related
I am trying to remove some spaces from a few dynamically generated strings. Which space I remove depends on the length of the string. The strings change all the time so in order to know how many spaces there are, I iterate over the string and increment a variable every time the iteration encounters a space. I can already remove all of a specific type of character with str.replace(' ',''); where 'str' is the name of my string, but I only need to remove a specific occurrence of a space, not all the spaces. So let's say my string is
var str = "Hello, this is a test.";
How can I remove ONLY the space after the word "is"? (Assuming that the next string will be different so I can't just write str.replace('is ','is'); because the word "is" might not be in the next string).
I checked documentation on .replace, but there are no other parameters that it accepts so I can't tell it just to replace the nth instance of a space.
If you want to go by indexes of the spaces:
var str = 'Hello, this is a test.';
function replace(str, indexes){
return str.split(' ').reduce(function(prev, curr, i){
var separator = ~indexes.indexOf(i) ? '' : ' ';
return prev + separator + curr;
});
}
console.log(replace(str, [2,3]));
http://jsfiddle.net/96Lvpcew/1/
As it is easy for you to get the index of the space (as you are iterating over the string) , you can create a new string without the space by doing:
str = str.substr(0, index)+ str.substr(index);
where index is the index of the space you want to remove.
I came up with this for unknown indices
function removeNthSpace(str, n) {
var spacelessArray = str.split(' ');
return spacelessArray
.slice(0, n - 1) // left prefix part may be '', saves spaces
.concat([spacelessArray.slice(n - 1, n + 1).join('')]) // middle part: the one without the space
.concat(spacelessArray.slice(n + 1)).join(' '); // right part, saves spaces
}
Do you know which space you want to remove because of word count or chars count?
If char count, you can Rafaels Cardoso's answer,
If word count you can split them with space and join however you want:
var wordArray = str.split(" ");
var newStr = "";
wordIndex = 3; // or whatever you want
for (i; i<wordArray.length; i++) {
newStr+=wordArray[i];
if (i!=wordIndex) {
newStr+=' ';
}
}
I think your best bet is to split the string into an array based on placement of spaces in the string, splice off the space you don't want, and rejoin the array into a string.
Check this out:
var x = "Hello, this is a test.";
var n = 3; // we want to remove the third space
var arr = x.split(/([ ])/); // copy to an array based on space placement
// arr: ["Hello,"," ","this"," ","is"," ","a"," ","test."]
arr.splice(n*2-1,1); // Remove the third space
x = arr.join("");
alert(x); // "Hello, this isa test."
Further Notes
The first thing to note is that str.replace(' ',''); will actually only replace the first instance of a space character. String.replace() also accepts a regular expression as the first parameter, which you'll want to use for more complex replacements.
To actually replace all spaces in the string, you could do str.replace(/ /g,""); and to replace all whitespace (including spaces, tabs, and newlines), you could do str.replace(/\s/g,"");
To fiddle around with different regular expressions and see what they mean, I recommend using http://www.regexr.com
A lot of the functions on the JavaScript String object that seem to take strings as parameters can also take regular expressions, including .split() and .search().
In Javascript I have several words separated by either a dot or one ore more whitepaces (or the end of the string).
I'd like to replace certain parts of it to insert custom information at the appropriate places.
Example:
var x = "test1.test test2 test3.xyz test4";
If there's a dot it should be replaced with ".X_"
If there's one or more space(s) and the word before does not contain a dot, replace with ".X "
So the desired output for the above example would be:
"test1.X_test test2.X test3.X_xyz test4.X"
Can I do this in one regex replace? If so, how?
If I need two or more what would they be?
Thanks a bunch.
Try this:
var str = 'test1.test test2 test3.xyz test4';
str = str.replace(/(\w+)\.(\w+)/g, '$1.X_$2');
str = str.replace(/( |^)(\w+)( |$)/g, '$1$2.X$3');
console.log(str);
In the first replace it replaces the dot in the dotted words with a .X_, where a dotted word is two words with a dot between them.
In the second replace it adds .X to words that have no dot, where words that have no dot are words that are preceded by a space OR the start of the string and are followed by a space OR the end of the string.
To answer this:
If there's a dot it should be replaced with ".X_"
If there's one or more spaces it should be replaced with ".X"
Do this:
x.replace(/\./g, '.X_').replace(/\s+/g, '.X');
Edit: To get your desired output (rather than your rules), you can do this:
var words = x.replace(/\s+/g, ' ').split(' ');
for (var i = 0, l = words.length; i < l; i++) {
if (words[i].indexOf('.') === -1) {
words[i] += ".X";
}
else {
words[i] = words[i].replace(/\./g, '.X_');
}
}
x = words.join(' ');
Basically...
Strip all multiple spaces and create an array of "words"
Loop through each word.
If it doesn't have a period in it, then add ".X" to the end of the word
Else, replace the periods with ".X_"
Join the "words" back into a string and separate it by spaces.
Edit 2:
Here's a solution using only javascript's replace function:
x.replace(/\s+/g, ' ') // replace multiple spaces with one space
.replace(/\./g, '.X_') // replace dots with .X_
// find words without dots and add a ".X" to the end
.replace(/(^|\s)([^\s\.]+)($|\s)/g, "$1$2.X$3");
I want to validate following text using regular expressions
integer(1..any)/'fs' or 'sf'/ + or - /integer(1..any)/(h) or (m) or (d)
samples :
1) 8fs+60h
2) 10sf-30m
3) 2fs+3h
3) 15sf-20m
i tried with this
function checkRegx(str,id){
var arr = strSplit(str);
var regx_FS =/\wFS\w|\d{0,9}\d[hmd]/gi;
for (var i in arr){
var str_ = arr[i];
console.log(str_);
var is_ok = str_.match(regx_FS);
var err_pos = str_.search(regx_FS);
if(is_ok){
console.log(' ID from ok ' + id);
$('#'+id).text('Format Error');
break;
}else{
console.log(' ID from fail ' + id);
$('#'+id).text('');
}
}
}
but it is not working
please can any one help me to make this correct
This should do it:
/^[1-9]\d*(?:fs|sf)[-+][1-9]\d*[hmd]$/i
You were close, but you seem to be missing some basic regex comprehension.
First of all, the ^ and $ just make sure you're matching the entire string. Otherwise any junk before or after will count as valid.
The formation [1-9]\d* allows for any integer from 1 upwards (and any number of digits long).
(?:fs|sf) is an alternation (the ?: is to make the group non-capturing) to allow for both options.
[-+] and [hmd] are character classes allowing to match any one of the characters in there.
That final i allows the letters to be lowercase or uppercase.
I don't see how the expression you tried relates anyhow to the description you gave us. What you want is
/\d+(fs|sf)[+-]\d+[hmd]/
Since you seem to know a bit about regular expressions I won't give a step-by-step explanation :-)
If you need exclude zero from the "integer" matches, use [1-9]\d* instead. Not sure whether by "(1..any)" you meant the number of digits or the number itself.
Looking on the code, you
should not use for in enumerations on arrays
will need string start and end anchors to check whether _str exactly matches the regex (instead of only some part)
don't need the global flag on the regex
rather might use the RegExp test method than match - you don't need a result string but only whether it did match or not
are not using the err_pos variable anywhere, and it hardly will work with search
function checkRegx(str, id) {
var arr = strSplit(str);
var regx_FS = /^\d+(fs|sf)[+-]\d+[hmd]$/i;
for (var i=0; i<arr.length; i++) {
var str = arr[i];
console.log(str);
if (regx_FS.test(str) {
console.log(' ID from ok ' + id);
$('#'+id).text('Format Error');
break;
} else {
console.log(' ID from fail ' + id);
$('#'+id).text('');
}
}
}
Btw, it would be better to separate the validation (regex, array split, iteration) from the output (id, jQuery, logs) into two functions.
Try something like this:
/^\d+(?:fs|sf)[-+]\d+[hmd]$/i
I am trying to use XRegExp to test if a string is a valid word according to these criteria:
The string begins with one or more Unicode letters, followed by
an apostrophe (') followed by one or more Unicode letters, repeated 0 or more times.
The string ends immediately after the matched pattern.
That is, it will match these terms
Hello can't Alah'u'u'v'oo O'reilly
but not these
eatin' 'sup 'til
I am trying this pattern,
^(\\p{L})+('(\\p{L})+)*$
but it won't match any words that contain apostrophes. What am I doing wrong?
EDIT: The code using the regex
var separateWords = function(text) {
var word = XRegExp("(\\p{L})+('(\\p{L})+)*$");
var splits = [];
for (var i = 0; i < text.length; i++) {
var item = text[i];
while (i + 1 < text.length && word.test(item + text[i + 1])) {
item += text[i + 1];
i++;
}
splits.push(item);
}
return splits;
};
I think you will need to omit the string start/end anchors to match single words:
"(\\p{L})+('(\\p{L})+)*"
Also I'm not sure what those capturing groups are needed for (that may depend on your application), but you could shorten them to
"\\p{L}+('\\p{L}+)*"
Try this regex:
^[^'](?:[\w']*[^'])?$
First it checks to ensure the first character is not an apostrophe. Then it either gets any number of word characters or apostrophes followed by anything other than an apostrophe, or it gets nothing (one-letter word).
Am I missing something in my code? It seems to only grab the first letter, and the while loop, doesn't go onto the next word. So what could I be missing?
function acr(s){
var words, acronym, nextWord;
words = s.split();
acronym= "";
index = 0
while (index<words.length) {
nextWord = words[index];
acronym = acronym + nextWord.charAt(0);
index = index + 1 ;
}
return acronym
}
If you only care about IE9+ then the answer can be made shorter:
function acronym(text) {
return text
.split(/\s/)
.reduce(function(accumulator, word) {
return accumulator + word.charAt(0);
}, '');
}
console.log(acronym('three letter acronym'));
If you can use arrow functions then it can be made shorter still:
function acronym(text) {
return text
.split(/\s/)
.reduce((accumulator, word) => accumulator + word.charAt(0), '');
}
console.log(acronym('three letter acronym'));
Add the separator to the split:
function acr(s){
var words, acronym, nextWord;
words = s.split(' ');
acronym= "";
index = 0
while (index<words.length) {
nextWord = words[index];
acronym = acronym + nextWord.charAt(0);
index = index + 1 ;
}
return acronym
}
JS Fiddle demo;
Revised the above to make it a little more demonstrative, and also interactive: JS Fiddle demo.
Edited to add references and explanation:
Because no separator was supplied the string remains un-split; therefore the while was operating correctly (as words.length is equal to 1), and so returns only the first letter of the string:
[Separator] specifies the character to use for separating the string. The separator is treated as a string or a regular expression. If separator is omitted, the array returned contains one element consisting of the entire string.
Reference:
split(), at MDC Docs
You forgot to split on whitespace:
words = s.split(/\s/);
You can have this in even lesser code. Try this
s.match(/\b(\w)/g).join("").toUpperCase()