How to reverse a string in place without reversing the punctuation? - javascript

I am trying to reverse the words in a string without any effect on punctuation.
This is my current code:
function reverse(str) {
str = str.split("").reverse().join("");
str = str.split(" ").reverse().join(" ");
console.log(str)
};
reverse("This is fun, hopefully.")
The result of the above function is sihT si ,nuf .yllufepoh
while I am trying to to get it like sihT si nuf, yllufepoh.

Another approach is to replace all sequences of letters with their reversed forms using replace and a regular expression, e.g.
function reverseWords(s) {
return s.replace(/[a-z]+/ig, function(w){return w.split('').reverse().join('')});
}
document.write(reverseWords("This is fun, hopefully.")); // sihT si nuf, yllufepoh.
If you wish to include numbers as word characters (w.g. W3C), then the regular expression should be:
/\w+/g

Split the sentence on word boundaries, which doesn't consume any of the string,
then split each word into its letters (non-spaces with \S) using a lookahead ?= so those aren't consumed.
Reverse the array of the letters, then rejoin them with no separator .join("")
and finally rejoin the sentence, again with no separator because the spaces between the words were retained when originally splitting on word boundaries.
var sentence = "This is fun, hopefully.";
sentence.split(/\b/)
.map(w => w.split(/(?=\S)/)
.reverse()
.join("") )
.join("");
Doing this in Chrome's javascript console produced the output:
"sihT si nuf, yllufepoh."
Note this doesn't correctly handle a run of punctuation. For example hopefully!? would become yllufepoh?!, reversing the punctuation too.

You can do better with Regular Expressions, but this is a simple solution that I just wrote.
function reverse(str){
var out = '';
var word = '';
for (var i=0;i<str.length;i++) {
// your punctuation characters
if (',.!? '.indexOf(str[i]) == -1) word += str[i];
else {
out += word.split('').reverse().join('');
out += str[i];
word = '';
}
}
return out;
};
console.log(reverse("This is fun, hopefully."));

Related

By using replace and regex: I have captured c, but I want to set it at the end of osonant plus “ay” with replace in Javascript

Here is he link: https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/intermediate-algorithm-scripting/pig-latin.
By using replace and regex: I have captured c, but I want to set it at the end of onsonant plus ay using the replace function in JavaScript
Here is my code:
function translatePigLatin(str) {
let regEx=/([bcd-fgh-klmn-pqrst-vwxyz])/i
console.log(str.replace(regEx, '$1,'))
}
translatePigLatin("consonant");
See if that's what you want
function translatePigLatin(str) {
let regx = /(.*?)([^aeiou])(.*)/i
console.log(str.replace(regx, '$1$3ay$2'))
}
translatePigLatin("consonant")
// output onsonantayc
Your question is a bit vague, if not add more information in the comments
#Edited
Pig Latin is a way of altering English Words. The rules are as
follows:
If a word begins with a consonant, take the first consonant or consonant cluster, move it to the end of the word, and add "ay" to it.
If a word begins with a vowel, just add "way" at the end.
A possible solution:
function translatePigLatin(str) {
if (!/[aeiou]/.test(str)) { // if it does not contain vowels
return str + "ay";
} else if (/^[aeiou]/.test(str)) { // if it starts with a vowel
return str + "way";
} else { // if it starts with a consonant and has vowels
let regx = /(.*?)([aeiou])(.*)/i;
return str.replace(regx, "$2$3$1ay");
}
}
console.log(translatePigLatin("pig")); // igpay
console.log(translatePigLatin("rythm")); // rythmay
console.log(translatePigLatin("consonant")); // onsonantcay
The regular expression /(.*?)([aeiou])(.*)/i means:
(.*?) match as minimum characters as possible
([aeiou]) followed by a vowel and
(.*) followed by the rest of the string.
By usinig the parenthesis, we are creating backreferences $1, $2, $3 that will store each of these values for later use with the replace method.

Using regex, extract values from a string in javascript

Need to extract values from a string using regex(for perf reasons).
Cases might be as follows:
RED,100
RED,"100"
RED,"100,"
RED,"100\"ABC\"200"
The resulting separated [label, value] array should be:
['RED','100']
['RED','100']
['RED','100,']
['RED','100"ABC"200']
I looked into solutions and a popular library even, just splits the entire string to get the values,
e.g. 'RED,100'.split(/,/) might just do the thing.
But I was trying to make a regex with comma, which splits only if that comma is not enclosed within a quotes type value.
This isnt a standard CSV behaviour might be. But its very easy for end-user to enter values.
enter label,value. Do whatever inside value, if thats surrounded by quotes. If you wanna contain quotes, use a backslash.
Any help is appreciated.
You can use this regex that takes care of escaped quotes in string:
/"[^"\\]*(?:\\.[^"\\]*)*"|[^,"]+/g
RegEx Explanation:
": Match a literal opening quote
[^"\\]*: Match 0 or more of any character that is not \ and not a quote
(?:\\.[^"\\]*)*: Followed by escaped character and another non-quote, non-\. Match 0 or more of this combination to get through all escaped characters
": Match closing quote
|: OR (alternation)
[^,"]+: Match 1+ of non-quote, non-comma string
RegEx Demo
const regex = /"[^"\\]*(?:\\.[^"\\]*)*"|[^,"]+/g;
const arr = [`RED,100`, `RED,"100"`, `RED,"100,"`,
`RED,"100\\"ABC\\"200"`];
let m;
for (var i = 0; i < arr.length; i++) {
var str = arr[i];
var result = [];
while ((m = regex.exec(str)) !== null) {
result.push(m[0]);
}
console.log("Input:", str, ":: Result =>", result);
}
You could use String#match and take only the groups.
var array = ['RED,100', 'RED,"100"', 'RED,"100,"', 'RED,"100\"ABC\"200"'];
console.log(array.map(s => s.match(/^([^,]+),(.*)$/).slice(1)))

How to get the last alphabetic character in string?

Here, I want to give each character a space except for the last alphabetic one:
var str = "test"
var result = "";
for (var i = 0; i < str.length; i++) {
result += (/*condition*/) ? str[i]
: str[i] + " ";
}
console.log(result);
So it prints "t e s t".
I tried this (i === str.length - 1) but it didn't work when a string had period(.) as it's last character ("test.") while I wanna target only alphabetics.
You can use a regular expression to remove all non-alphabetical characters first, and then do a split/join combination to insert the spaces (or use another regex):
var str = "don't test.";
var result = str.replace(/[^a-z]/gi, '').split('').join(' ');
console.log(result);
"testasdf. asdf asdf asd.d?".replace(/./g,"$& ").replace(/([A-Za-z]) ([^A-Za-z]*)$/, '$1$2')
the first replace add a space to all char
the second replace removes the space after the last letter
console.log("testasdf?".replace(/./g,"$& ").replace(/([A-Za-z]) ([^A-Za-z]*)$/, '$1$2'));
console.log("Super test ! Yes".replace(/./g,"$& ").replace(/([A-Za-z]) ([^A-Za-z]*)$/, '$1$2'));
There is such a feature like lookahead assertions.
So it could be
str.replace(/(\w)(?=.*\w)/, "$1")
Using a regex replace function, you can space out all of your characters like this:
"test string, with several words.".replace(/\w{2,}/g, match => match.split('').join(' '))
Explanation
\w{2,} match 2 or more alphabetic characters
match.split('').join(' ') split each match into characters, and rejoin with spaces between

limit character number for specific words starting with # in JavaScript

I have some issues, I need to "limit" character for specific word with special character (10 characters)
example in a textarea :
The #dog is here, I need a #rest and this is not #availableeeeeeeee for now
the word "availableeeeeeeee" needs to be cut when I reach 10 characters
Desired results
The #dog is here, I need a #rest and this is not #availablee for now
My question is how to limit characters for each word that containing a hashtag?
Thanks
1. Regex Solution:
You can use .replace() method with the following regex /(#\w{10})\[\w\d\]+/g, it will remove the extra characters:
str = str.replace(/(#\w{10})[\w\d]+/g, '$1');
Demo:
var str = "The #dog is here, I need a #rest and this is not #availableeeeeeeee for now";
str = str.replace(/(#\w{10})[\w\d]+/g, '$1');
console.log(str);
Note:
This regex matches the words starting with # using a matching group to get only the first 10 characters.
Full match #availableeeeeeeee
Group 1. n/a #availablee
And the .replace() call will keep only the matched group from the regex and skip the extra characters.
Note that you need to attach this code in the onchange event handler of your textarea.
2. split() Solution:
If you want to go with a solution that doesn't use Regex, you can use .split() method with Array.prototype.map() like this:
str = str.split(" ").map(function(item){
return item.startsWith("#") && item.length > 11 ? item.substr(0,11) : item;
}).join(" ");
Demo:
var str = "The #dog is here, I need a #rest and this is not #availableeeeeeeee for now";
str = str.split(" ").map(function(item){
return item.startsWith("#") && item.length > 11 ? item.substr(0,11) : item;
}).join(" ");
console.log(str);
a simple solution with javascript could be, to split text area all words into array. iterate it and validate word length.
var value = $('#text').val();
var maxSize = 10;
var words = value.trim().replace(regex, ' ').split(' ');
for(var wlength= 0 ; wlength < words.length; wlength++)
{
if(words[wlength] > maxSize)
{
alert('size exceeds max allowed');
}
}
you can try not allowing typing itself after 10 characters for any word by regular expression inline validation in HTML directly.
Well, I think you can try the following.
Using split() method will cut the string in words, then forEach word if it startsWith a '#', we substr it up to 10 + 1 characters. Finally, join everybody to obtain the final result :).
string="The #dog is here, I need a #rest and this is not #availableeeeeeeee for now"
var result = []
string.split(" ").forEach(function(item){
if (item.startsWith("#")){
result.push(item.substr(0,11));
} else result.push(item);
});
console.log(result.join(" "));

How to make first character uppercase of all words in JavaScript?

I have searched for solution but did not find yet.
I have the following string.
1. hello
2. HELLO
3. hello_world
4. HELLO_WORLD
5. Hello World
I want to convert them to following:
1. Hello
2. Hello
3. HelloWorld
4. HelloWorld
5. HelloWorld
If there is No space and underscore in string just uppercase first and all others to lowercase. If words are separated by underscore or space then Uppercase first letter of each word and remove space and underscore. How can I do this in JavaScript.
Thanks
Here is a regex solution:
First lowercase the string:
str = str.toLowerCase();
Replace all _ and spaces and first characters in a word with upper case character:
str = str.replace(/(?:_| |\b)(\w)/g, function(str, p1) { return p1.toUpperCase()})
DEMO
Update: Less steps ;)
Explanation:
/ // start of regex
(?: // starts a non capturing group
_| |\b // match underscore, space, or any other word boundary character
// (which in the end is only the beginning of the string ^)
) // end of group
( // start capturing group
\w // match word character
) // end of group
/g // and of regex and search the whole string
The value of the capturing group is available as p1 in the function, and the whole expression is replaced by the return value of the function.
You could do something like this:
function toPascalCase(str) {
var arr = str.split(/\s|_/);
for(var i=0,l=arr.length; i<l; i++) {
arr[i] = arr[i].substr(0,1).toUpperCase() +
(arr[i].length > 1 ? arr[i].substr(1).toLowerCase() : "");
}
return arr.join("");
}
You can test it out here, the approach is pretty simple, .split() the string into an array when finding either whitespace or an underscore. Then loop through the array, upper-casing the first letter, lower-casing the rest...then take that array of title-case words and .join() it together into one string again.
function foo(str) {
return $(str.split(/\s|_/)).map(function() {
return this.charAt(0).toUpperCase() + this.slice(1).toLowerCase();
}).get().join("");
}
Working demo: http://jsfiddle.net/KSJe3/3/
(I used Nicks regular expression in the demo)
Edit: Another version of the code - I replaced map() with $.map():
function foo(str) {
return $.map(str.split(/\s|_/), function(word) {
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
}).join("");
}
Working demo: http://jsfiddle.net/KSJe3/4/
An ES6 / functional update of #NickCraver's answer. As with #NickCraver's answer this function will handle multiple spaces / underscores properly by filtering them out.
const pascalWord = x => x[0].toUpperCase() + x.slice(1).toLowerCase();
const toPascalCase2 = (str) => (
str.split(/\s|_/)
.filter(x => x)
.map(pascalWord)
.join('')
);
const tests = [
'hello',
'HELLO',
'hello_world',
'HELLO_WORLD',
'Hello World',
'HELLO__WORLD__',
'Hello World_',
].map(toPascalCase2).join('<br>');
document.write(tests);
var city = city.replace(/\s+/g,' ') //replace all spaceses to singele speace
city = city.replace(/\b\w/g,city => city .toUpperCase()) //after speace letter convert capital

Categories