I am having trouble below javaScript problem.
Question:
You have been given a string s, which is supposed to be a sentence. However, someone forgot to put spaces between the different words, and for some reason they capitalized the first letter of every word. Return the sentence after making the following amendments:
Put a single space between the words.
Convert the uppercase letters to lowercase.
Example
"CodefightsIsAwesome", the output should be "codefights is awesome";
"Hello", the output should be "hello".
My current code is:
Right now, my second for-loop just manually slices the parts from the string.
How can I make this dynamic and insert "space" in front of the Capital String?
You can use String.prototype.match() with RegExp /[A-Z][^A-Z]*/g to match A-Z followed by one or more characters which are not A-Z, or character at end of string; chain Array.prototype.map() to call .toLowerCase() on matched words, .join() with parameter " " to include space character between matches at resulting string.
var str = "CodefightsIsAwesome";
var res = str.match(/[A-Z][^A-Z]*/g).map(word => word.toLowerCase()).join(" ");
console.log(res);
Alternatively, as suggested by #FissureKing, you can use String.prototype.repalce() with .trim() and .toLowerCase() chained
var str = "CodefightsIsAwesome";
var res = str.replace(/[A-Z][^A-Z]*/g, word => word + ' ').trim().toLowerCase();
console.log(res);
Rather than coding a loop, I'd do it in one line with a (reasonably) simple string replacement:
function amendTheSentence(s) {
return s.replace(/[A-Z]/g, function(m) { return " " + m.toLowerCase() })
.replace(/^ /, "");
}
console.log(amendTheSentence("CodefightsIsAwesome"));
console.log(amendTheSentence("noCapitalOnFirstWord"));
console.log(amendTheSentence("ThereIsNobodyCrazierThanI"));
That is, match any uppercase letter with the regular expression /[A-Z]/, replace the matched letter with a space plus that letter in lowercase, then remove any space that was added at the start of the string.
Further reading:
String .replace() method
Regular expressions
We can loop through once.
The below assumes the very first character should always be capitalized in our return array. If that is not true, simply remove the first if block from below.
For each character after that, we check to see if it is capitalized. If so, we add it to our return array, prefaced with a space. If not, we add it as-is into our array.
Finally, we join the array back into a string and return it.
const sentence = "CodefightsIsAwesome";
const amend = function(s) {
ret = [];
for (let i = 0; i < s.length; i++) {
const char = s[i];
if (i === 0) {
ret.push(char.toUpperCase());
} else if (char.toUpperCase() === char) {
ret.push(` ${char.toLowerCase()}`);
} else {
ret.push(char);
}
}
return ret.join('');
};
console.log(amend(sentence));
Related
I want to convert a string to the sentence case. That is, uppercase the first character in each sentence and lowercase the following characters. I managed to do this. However, after splitting the string and converting it to a sentence case, I need to join it again with a corresponding character.
Here is my code that splits the string into sentences:
const string = "my seNTencE . My sentence! my another sentence. yEt another senTence? Again my sentence .";
function splitString(str) {
str = str.split(/[.!?]/);
for(let i = 0; i < str.length; i++) {
str[i] = str[i].trim();
}
for(let i = 0; i < str.length; i++) {
str[i] = str[i].charAt(0).toUpperCase() + str[i].slice(1).toLowerCase();
}
return str;
}
console.log(splitString(string));
In the return statement, I want to return joined strings. For example, the first sentence must end with a dot, and the second must end with an exclamation mark, etc. How to implement this?
str.split eliminates the result of the regex match from the string. If you want to keep it, you can place the separator in a lookbehind like this:
str.split(/(?<=[.!?])/);
The syntax (?<= ) means the regex will find positions that are preceded by punctuation, but won't include said punctuation in the match, so the split method will leave it in.
As a side note, keep in mind that this function will ruin acronyms, proper nouns, and the word I. Forcing the first letter after a period to be a capital letter is probably fine, but you will find that this function does more harm than good.
Use a regular expression with capture groups. This regex uses the lazy ? modifier so the match will end at the first [!.?], and the global g flag to grab all matches.
const string = "my seNTencE . My sentence! my another sentence. yEt another senTence? Again my sentence ."
const rx = /(.*?)([.!?])/g
const found = []
while (m = rx.exec(string)) {
let str = m[1].trim()
str = str.charAt(0).toUpperCase() + str.slice(1).toLowerCase()
found.push(str + m[2])
}
console.log(found)
Who can help me with the following
I create a rule with regex and I want remove all characters from the string if they not allowed.
I tried something by myself but I get not the result that I want
document.getElementById('item_price').onkeydown = function() {
var regex = /^(\d+[,]+\d{2})$/;
if (regex.test(this.value) == false ) {
this.value = this.value.replace(regex, "");
}
}
The characters that allowed are numbers and one komma.
Remove all letters, special characters and double kommas.
If the user types k12.40 the code must replace this string to 1240
Who can help me to the right direction?
This completely removes double occurrences of commas using regex, but keeps single ones.
// This should end up as 1,23243,09
let test = 'k1,23.2,,43d,0.9';
let replaced = test.replace(/([^(\d|,)]|,{2})/g, '')
console.log(replaced);
I don't believe there's an easy way to have a single Regex behave like you want. You can use a function to determine what to replace each character with, though:
// This should end up as 1232,4309 - allows one comma and any digits
let test = 'k12,3.2,,43,d0.9';
let foundComma = false;
let replaced = test.replace(/(,,)|[^\d]/g, function (item) {
if (item === ',' && !foundComma) {
foundComma = true;
return ',';
} else {
return '';
}
})
console.log(replaced);
This will loop through each non-digit. If its the first time a comma has appeared in this string, it will leave it. Otherwise, if it must be either another comma or a non-digit, and it will be replaced. It will also replace any double commas with nothing, even if it is the first set of commas - if you want it to be replaced with a single comma, you can remove the (,,) from the regex.
Regex to fetch all spaces as long as they are not enclosed in braces
This is for a javascript mention system
ex: "Speak #::{Joseph Empyre}{b0268efc-0002-485b-b3b0-174fad6b87fc}, all right?"
Need to get:
[ "Speak ", "#::{Joseph
Empyre}{b0268efc-0002-485b-b3b0-174fad6b87fc}", ",", "all ", "right?"
]
[Edit]
Solved in: https://codesandbox.io/s/rough-http-8sgk2
Sorry for my bad english
I interpreted your question as you said to to fetch all spaces as long as they are not enclosed in braces, although your result example isn't what I would expect. Your example result contains a space after speak, as well as a separate match for the , after the {} groups. My output below shows what I would expect for what I think you are asking for, a list of strings split on just the spaces outside of braces.
const str =
"Speak #::{Joseph Empyre}{b0268efc-0002-485b-b3b0-174fad6b87fc}, all right?";
// This regex matches both pairs of {} with things inside and spaces
// It will not properly handle nested {{}}
// It does this such that instead of capturing the spaces inside the {},
// it instead captures the whole of the {} group, spaces and all,
// so we can discard those later
var re = /(?:\{[^}]*?\})|( )/g;
var match;
var matches = [];
while ((match = re.exec(str)) != null) {
matches.push(match);
}
var cutString = str;
var splitPieces = [];
for (var len=matches.length, i=len - 1; i>=0; i--) {
match = matches[i];
// Since we have matched both groups of {} and spaces, ignore the {} matches
// just look at the matches that are exactly a space
if(match[0] == ' ') {
// Note that if there is a trailing space at the end of the string,
// we will still treat it as delimiter and give an empty string
// after it as a split element
// If this is undesirable, check if match.index + 1 >= cutString.length first
splitPieces.unshift(cutString.slice(match.index + 1));
cutString = cutString.slice(0, match.index);
}
}
splitPieces.unshift(cutString);
console.log(splitPieces)
Console:
["Speak", "#::{Joseph Empyre}{b0268efc-0002-485b-b3b0-174fad6b87fc},", "all", "right?"]
I am trying to get this result: 'Summer-is-here'. Why does the code below generate extra spaces? (Current result: '-Summer--Is- -Here-').
function spinalCase(str) {
var newA = str.split(/([A-Z][a-z]*)/).join("-");
return newA;
}
spinalCase("SummerIs Here");
You are using a variety of split where the regexp contains a capturing group (inside parentheses), which has a specific meaning, namely to include all the splitting strings in the result. So your result becomes:
["", "Summer", "", "Is", " ", "Here", ""]
Joining that with - gives you the result you see. But you can't just remove the unnecessary capture group from the regexp, because then the split would give you
["", "", " ", ""]
because you are splitting on zero-width strings, due to the * in your regexp. So this doesn't really work.
If you want to use split, try splitting on zero-width or space-only matches looking ahead to a uppercase letter:
> "SummerIs Here".split(/\s*(?=[A-Z])/)
^^^^^^^^^ LOOK-AHEAD
< ["Summer", "Is", "Here"]
Now you can join that to get the result you want, but without the lowercase mapping, which you could do with:
"SummerIs Here" .
split(/\s*(?=[A-Z])/) .
map(function(elt, i) { return i ? elt.toLowerCase() : elt; }) .
join('-')
which gives you want you want.
Using replace as suggested in another answer is also a perfectly viable solution. In terms of best practices, consider the following code from Ember:
var DECAMELIZE_REGEXP = /([a-z\d])([A-Z])/g;
var DASHERIZE_REGEXP = /[ _]/g;
function decamelize(str) {
return str.replace(DECAMELIZE_REGEXP, '$1_$2').toLowerCase();
}
function dasherize(str) {
return decamelize(str).replace(DASHERIZE_REGEXP, '-');
}
First, decamelize puts an underscore _ in between two-character sequences of lower-case letter (or digit) and upper-case letter. Then, dasherize replaces the underscore with a dash. This works perfectly except that it lower-cases the first word in the string. You can sort of combine decamelize and dasherize here with
var SPINALIZE_REGEXP = /([a-z\d])\s*([A-Z])/g;
function spinalCase(str) {
return str.replace(SPINALIZE_REGEXP, '$1-$2').toLowerCase();
}
You want to separate capitalized words, but you are trying to split the string on capitalized words that's why you get those empty strings and spaces.
I think you are looking for this :
var newA = str.match(/[A-Z][a-z]*/g).join("-");
([A-Z][a-z]*) *(?!$|[a-z])
You can simply do a replace by $1-.See demo.
https://regex101.com/r/nL7aZ2/1
var re = /([A-Z][a-z]*) *(?!$|[a-z])/g;
var str = 'SummerIs Here';
var subst = '$1-';
var result = str.replace(re, subst);
var newA = str.split(/ |(?=[A-Z])/).join("-");
You can change the regex like:
/ |(?=[A-Z])/ or /\s*(?=[A-Z])/
Result:
Summer-Is-Here
I have an Acrobat form with some text fields with multiline on. My goal is to convert to uppercase the first letter of any sentence (look for dots) and also the first letter of any new line (after return has been pressed).
I can run each transformation separately, but do not know how to run them together.
To capitalize sentences I use the following code as custom convalidation :
// make an array split at dot
var aInput = event.value.split(". ");
var sCharacter = '';
var sWord='';
// for each element of word array, capitalize the first letter
for(i = 0; i <aInput.length; i++)
{
aInput[i] = aInput[i].substr(0, 1).toUpperCase() + aInput[i].substr(1) .toLowerCase();
}
// rebuild input string with modified words with dots
event.value = aInput.join('. ');
To capitalize new lines I replace ". " with "\r".
Thanks in advance for any help.
You can get the first character of each sentence with RegExp :
event.value = event.value.replace(/.+?[\.\?\!](\s|$)/g, function (txt) {
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
});
Demo : http://jsfiddle.net/00kzc370/
Regular Expression explained :
/.+?[\.\?\!](\s|$)/g is a regular expression.
.+?[\.\?\!](\s|$) is a pattern (to be used in a search) that match sentences ended by ., ? or ! and followed by a whitespace character.
g is a modifier. (Perform a global match (find all matches rather than stopping after the first match)).
Source : http://www.w3schools.com/jsref/jsref_obj_regexp.asp