Making any letter in () a lower case all other letters uppercase - javascript

I am trying to make a variable string uppercase and letters that are within () lower case. string will be what ever the user enters so do not know what it will be ahead of time.
user entry examples
What is entered
(H)e(L)lo
what is expected outcome
(h)E(l)LO
What is entered
(H)ELLO (W)orld
what is expected outcome
(h)ELLO (w)ORLD
here is what i have tried but can only get it to work if the () are at the end of the string.
if(getElementById("ID")){
var headline = getElementById("ID").getValue();
var headlineUpper = headline.toUpperCase();
var IndexOf = headlineUpper.indexOf("(");
if(IndexOf === -1){
template.getRegionNode("Region").setValue(headlineUpper);
}
else{
var plus = parseInt(IndexOf + 1);
var replacing = headlineUpper[plus];
var lower = replacing.toLowerCase();
var render = headlineUpper.replace(headlineUpper.substring(plus), lower + ")");
getElementById("Region").setValue(render);
}
}
Do to our system i am only able to use vanilla javascript. i have asked a similar question before with one () but now we are expecting more then one () in the string.

You can use the .replace() method with a regular expression. First you can make your string all uppercase using .toUpperCase(). Then, you can match all characters in-between ( and ) and use the replacement function of the replace method to convert the matched characters to lowercase.
See example below:
function uppercase(str) {
return str.toUpperCase().replace(/\(.*?\)/g, function(m) {
return m.toLowerCase();
});
}
console.log(uppercase("(H)e(L)lo")); // (h)E(l)LO
console.log(uppercase("(H)ELLO (W)orld")); // (h)ELLO (w)ORLD
If you can support ES6 you can clean up the above function with arrow functions:
const uppercase = str =>
str.toUpperCase().replace(/\(.*?\)/g, m => m.toLowerCase());
console.log(uppercase("(H)e(L)lo")); // (h)E(l)LO
console.log(uppercase("(H)ELLO (W)orld")); // (h)ELLO (w)ORLD

Just in case you want a faster regex alternative, you can use a negated character (^)) regex instead of laziness (?). It's faster as it doesn't require backtracking.
const uppercase = str =>
str.toUpperCase().replace(/\([^)]+\)/g, m => m.toLowerCase());

I tried to do it without use of any regex. I'm storing the indexes of all ( and ).
String.prototype.replaceBetween = function (start, end, what) {
return this.substring(0, start) + what + this.substring(end);
};
function changeCase(str) {
str = str.toLowerCase();
let startIndex = str.split('').map((el, index) => (el === '(') ? index : null).filter(el => el !== null);
let endIndex = str.split('').map((el, index) => (el === ')') ? index : null).filter(el => el !== null);
Array.from(Array(startIndex.length + 1).keys()).forEach(index => {
if (index !== startIndex.length) {
let indsideParentheses = '(' + str.substring(startIndex[index] + 1, endIndex[index]).toUpperCase() + ')';
str = str.replaceBetween(startIndex[index], endIndex[index] + 1, indsideParentheses);
}
});
return str;
}
let str = '(h)ELLO (w)ORLD'
console.log(changeCase(str));

Related

Replace consecutive white spaces between words with one hyphen

The question is from freecodecamp Link
Fill in the urlSlug function so it converts a string title and returns the hyphenated version for the URL. You can use any of the methods covered in this section, and don't use replace. Here are the requirements:
The input is a string with spaces and title-cased words
The output is a string with the spaces between words replaced by a
hyphen (-)
The output should be all lower-cased letters
The output should not have any spaces
// the global variable
var globalTitle = " Winter Is Coming";
function urlSlug(title) {
let toArr = title.split("");
let newArr = toArr.map(a=> {
if(a==" "){
a= "-";
}
return a.toLowerCase();
} );
if(newArr[0] == "-"){
newArr.splice(0,1);
}
let finalArr = newArr.join("");
return finalArr;
}
// Add your code above this line
var winterComing = urlSlug(globalTitle); // Should be "winter-is-coming"
console.log(urlSlug(globalTitle));
Right now I have not been able to solve how I could get rid of the extra hyphen from the output.
I'm not supposed to use replace.
You could do this easily using trim() and a simple regex:
var globalTitle = " Winter Is Coming Now ";
var slug = globalTitle.trim().replace(/[ ]+/g, '-').toLowerCase();
console.log(slug);
[ ]+ ensures that any number of spaces (1 or more) gets replaced with a minus sign once.
If for some reason you can't use replace, you could use Array.filter() like so:
var title = " Winter Is Coming Now ";
var slug = title.split(" ").filter(word => word.length > 0).join("-").toLowerCase();
console.log(slug);
I was working on it till now , Haven't looked at the answers.
But I solved it this way. Might be inefficient.
// the global variable
var globalTitle = "Winter Is Coming";
function urlSlug(title) {
let toArr = title.split("");
let newArr = toArr.map(a=> {
if(a==" "){
a= "-";
}
return a.toLowerCase();
} );
if(newArr[0] == "-"){
newArr.splice(0,1);
}
for(let i=0;i<newArr.length;i++){
if(newArr[i-1]=="-"&& newArr[i]=="-")
{
newArr.splice(i,1,"");
}
}
let finalArr = newArr.join("");
return finalArr;
}
var winterComing = urlSlug(globalTitle); // Should be "winter-is-coming"
console.log(urlSlug(globalTitle));
Another option would be to continue your thought of split() and then use reduce to reduce the elements of the array to a single output:
var globalTitle = " Winter Is Coming";
function urlSlug(title) {
let split = title.split(' ');
return split.reduce((accumulator, currentValue, index) => {
if (currentValue.length > 0) {
accumulator += currentValue.toLowerCase();
accumulator += (index < split.length - 1) ? '-' : '';
}
return accumulator;
});
}
console.log(urlSlug(globalTitle));

How to get odd and even position characters from a string?

I'm trying to figure out how to remove every second character (starting from the first one) from a string in Javascript.
For example, the string "This is a test!" should become "hsi etTi sats!"
I also want to save every deleted character into another array.
I have tried using replace method and splice method, but wasn't able to get them to work properly. Mostly because replace only replaces the first character.
function encrypt(text, n) {
if (text === "NULL") return n;
if (n <= 0) return text;
var encArr = [];
var newString = text.split("");
var j = 0;
for (var i = 0; i < text.length; i += 2) {
encArr[j++] = text[i];
newString.splice(i, 1); // this line doesn't work properly
}
}
You could reduce the characters of the string and group them to separate arrays using the % operator. Use destructuring to get the 2D array returned to separate variables
let str = "This is a test!";
const [even, odd] = [...str].reduce((r,char,i) => (r[i%2].push(char), r), [[],[]])
console.log(odd.join(''))
console.log(even.join(''))
Using a for loop:
let str = "This is a test!",
odd = [],
even = [];
for (var i = 0; i < str.length; i++) {
i % 2 === 0
? even.push(str[i])
: odd.push(str[i])
}
console.log(odd.join(''))
console.log(even.join(''))
It would probably be easier to use a regular expression and .replace: capture two characters in separate capturing groups, add the first character to a string, and replace with the second character. Then, you'll have first half of the output you need in one string, and the second in another: just concatenate them together and return:
function encrypt(text) {
let removedText = '';
const replacedText1 = text.replace(/(.)(.)?/g, (_, firstChar, secondChar) => {
// in case the match was at the end of the string,
// and the string has an odd number of characters:
if (!secondChar) secondChar = '';
// remove the firstChar from the string, while adding it to removedText:
removedText += firstChar;
return secondChar;
});
return replacedText1 + removedText;
}
console.log(encrypt('This is a test!'));
Pretty simple with .reduce() to create the two arrays you seem to want.
function encrypt(text) {
return text.split("")
.reduce(({odd, even}, c, i) =>
i % 2 ? {odd: [...odd, c], even} : {odd, even: [...even, c]}
, {odd: [], even: []})
}
console.log(encrypt("This is a test!"));
They can be converted to strings by using .join("") if you desire.
I think you were on the right track. What you missed is replace is using either a string or RegExp.
The replace() method returns a new string with some or all matches of a pattern replaced by a replacement. The pattern can be a string or a RegExp, and the replacement can be a string or a function to be called for each match. If pattern is a string, only the first occurrence will be replaced.
Source: String.prototype.replace()
If you are replacing a value (and not a regular expression), only the first instance of the value will be replaced. To replace all occurrences of a specified value, use the global (g) modifier
Source: JavaScript String replace() Method
So my suggestion would be to continue still with replace and pass the right RegExp to the function, I guess you can figure out from this example - this removes every second occurrence for char 't':
let count = 0;
let testString = 'test test test test';
console.log('original', testString);
// global modifier in RegExp
let result = testString.replace(/t/g, function (match) {
count++;
return (count % 2 === 0) ? '' : match;
});
console.log('removed', result);
like this?
var text = "This is a test!"
var result = ""
var rest = ""
for(var i = 0; i < text.length; i++){
if( (i%2) != 0 ){
result += text[i]
} else{
rest += text[i]
}
}
console.log(result+rest)
Maybe with split, filter and join:
const remaining = myString.split('').filter((char, i) => i % 2 !== 0).join('');
const deleted = myString.split('').filter((char, i) => i % 2 === 0).join('');
You could take an array and splice and push each second item to the end of the array.
function encrypt(string) {
var array = [...string],
i = 0,
l = array.length >> 1;
while (i <= l) array.push(array.splice(i++, 1)[0]);
return array.join('');
}
console.log(encrypt("This is a test!"));
function encrypt(text) {
text = text.split("");
var removed = []
var encrypted = text.filter((letter, index) => {
if(index % 2 == 0){
removed.push(letter)
return false;
}
return true
}).join("")
return {
full: encrypted + removed.join(""),
encrypted: encrypted,
removed: removed
}
}
console.log(encrypt("This is a test!"))
Splice does not work, because if you remove an element from an array in for loop indexes most probably will be wrong when removing another element.
I don't know how much you care about performance, but using regex is not very efficient.
Simple test for quite a long string shows that using filter function is on average about 3 times faster, which can make quite a difference when performed on very long strings or on many, many shorts ones.
function test(func, n){
var text = "";
for(var i = 0; i < n; ++i){
text += "a";
}
var start = new Date().getTime();
func(text);
var end = new Date().getTime();
var time = (end-start) / 1000.0;
console.log(func.name, " took ", time, " seconds")
return time;
}
function encryptREGEX(text) {
let removedText = '';
const replacedText1 = text.replace(/(.)(.)?/g, (_, firstChar, secondChar) => {
// in case the match was at the end of the string,
// and the string has an odd number of characters:
if (!secondChar) secondChar = '';
// remove the firstChar from the string, while adding it to removedText:
removedText += firstChar;
return secondChar;
});
return replacedText1 + removedText;
}
function encrypt(text) {
text = text.split("");
var removed = "";
var encrypted = text.filter((letter, index) => {
if(index % 2 == 0){
removed += letter;
return false;
}
return true
}).join("")
return encrypted + removed
}
var timeREGEX = test(encryptREGEX, 10000000);
var timeFilter = test(encrypt, 10000000);
console.log("Using filter is faster ", timeREGEX/timeFilter, " times")
Using actually an array for storing removed letters and then joining them is much more efficient, than using a string and concatenating letters to it.
I changed an array to string in filter solution to make it the same like in regex solution, so they are more comparable.

Invalid left-hand side in assignment expression

New person here working on a toy problem building a function that converts a string to camelcase anywhere there is a dash or an underscore. I have almost everything worked out except the second to last line of the function where I am trying to change the characters at each index (from my index array) to uppercase before I return the string. The error I am getting is bad assignment from the left side, but I'm not sure why. I've console logged both sides of the assignment and they seem to be doing what I want, but the assignment itself isn't working. Thank you for any help!
Here is the code:
function toCamelCase(str){
var stringArray = str.split('');
var indexArray = [];
stringArray.forEach(character => {
if (character === '-' || character === '_') {
var index = str.indexOf(character);
str = str.slice(0, index) + str.slice(index+1)
indexArray.push(index);
}
return character;
})
indexArray.forEach(index => {stringArray.splice(index, 1)});
string = stringArray.join('');
indexArray.forEach(index => {string.charAt(index) = string.charAt(index).toUpperCase()});
return string;
}
The problem is with using string.charAt() on the left hand side. That is not possible as you're trying to assign something to the result of a function, all in the same call. Store the value of string.charAt() in an intermediary variable and it should work. Check the code below for a working example, using a slightly different approach:
function toCamelCase(str){
var stringArray = str.split('');
var indexArray = [];
stringArray.forEach(character => {
if (character === '-' || character === '_') {
var index = str.indexOf(character);
str = str.slice(0, index) + str.slice(index+1)
indexArray.push(index);
}
return character;
});
indexArray.forEach(index => {stringArray.splice(index, 1)});
return stringArray.map((char, index) => {
return indexArray.includes(index) ? char.toUpperCase() : char;
}).join('');
}
Ah thank you both for pointing me in the right direction. Instead of joining it back to a string I took advantage of it being an array already and just looped through that first.
This code worked...
function toCamelCase(str){
var stringArray = str.split('');
var indexArray = [];
stringArray.forEach(character => {
if (character === '-' || character === '_') {
var index = str.indexOf(character);
str = str.slice(0, index) + str.slice(index+1)
indexArray.push(index);
}
return character;
})
indexArray.forEach(index => {stringArray.splice(index, 1)});
indexArray.forEach(index => {stringArray[index] = stringArray[index].toUpperCase()});
var string = stringArray.join('');
return string;
}
For taking an approach by iterating the characters, you could use a flag for the following upper case letter.
function toCamelCase(str) {
var upper = false;
return str
.split('')
.map(c => {
if (c === '-' || c === '_') {
upper = true;
return '';
}
if (upper) {
upper = false;
return c.toUpperCase();
}
return c;
})
.join('');
}
console.log(toCamelCase('foo----bar_baz'));
As strange as it sounds what fixed this error was to add ; semicolon at the end of line where the Parsing error: Invalid left-hand side in assignment expression occurred. More context here.

Trim specific character from a string

What's the JavaScript equivalent to this C# Method:
var x = "|f|oo||";
var y = x.Trim('|'); // "f|oo"
C# trims the selected character only at the beginning and end of the string!
One line is enough:
var x = '|f|oo||';
var y = x.replace(/^\|+|\|+$/g, '');
document.write(x + '<br />' + y);
^ beginning of the string
\|+ pipe, one or more times
| or
\|+ pipe, one or more times
$ end of the string
A general solution:
function trim (s, c) {
if (c === "]") c = "\\]";
if (c === "^") c = "\\^";
if (c === "\\") c = "\\\\";
return s.replace(new RegExp(
"^[" + c + "]+|[" + c + "]+$", "g"
), "");
}
chars = ".|]\\^";
for (c of chars) {
s = c + "foo" + c + c + "oo" + c + c + c;
console.log(s, "->", trim(s, c));
}
Parameter c is expected to be a character (a string of length 1).
As mentionned in the comments, it might be useful to support multiple characters, as it's quite common to trim multiple whitespace-like characters for example. To do this, MightyPork suggests to replace the ifs with the following line of code:
c = c.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
This part [-/\\^$*+?.()|[\]{}] is a set of special characters in regular expression syntax, and $& is a placeholder which stands for the matching character, meaning that the replace function escapes special characters. Try in your browser console:
> "{[hello]}".replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')
"\{\[hello\]\}"
Update: Was curious around the performance of different solutions and so I've updated a basic benchmark here:
https://www.measurethat.net/Benchmarks/Show/12738/0/trimming-leadingtrailing-characters
Some interesting and unexpected results running under Chrome.
https://www.measurethat.net/Benchmarks/ShowResult/182877
+-----------------------------------+-----------------------+
| Test name | Executions per second |
+-----------------------------------+-----------------------+
| Index Version (Jason Larke) | 949979.7 Ops/sec |
| Substring Version (Pho3niX83) | 197548.9 Ops/sec |
| Regex Version (leaf) | 107357.2 Ops/sec |
| Boolean Filter Version (mbaer3000)| 94162.3 Ops/sec |
| Spread Version (Robin F.) | 4242.8 Ops/sec |
+-----------------------------------+-----------------------+
Please note; tests were carried out on only a single test string (with both leading and trailing characters that needed trimming). In addition, this benchmark only gives an indication of raw speed; other factors like memory usage are also important to consider.
If you're dealing with longer strings I believe this should outperform most of the other options by reducing the number of allocated strings to either zero or one:
function trim(str, ch) {
var start = 0,
end = str.length;
while(start < end && str[start] === ch)
++start;
while(end > start && str[end - 1] === ch)
--end;
return (start > 0 || end < str.length) ? str.substring(start, end) : str;
}
// Usage:
trim('|hello|world|', '|'); // => 'hello|world'
Or if you want to trim from a set of multiple characters:
function trimAny(str, chars) {
var start = 0,
end = str.length;
while(start < end && chars.indexOf(str[start]) >= 0)
++start;
while(end > start && chars.indexOf(str[end - 1]) >= 0)
--end;
return (start > 0 || end < str.length) ? str.substring(start, end) : str;
}
// Usage:
trimAny('|hello|world ', [ '|', ' ' ]); // => 'hello|world'
// because '.indexOf' is used, you could also pass a string for the 2nd parameter:
trimAny('|hello| world ', '| '); // => 'hello|world'
EDIT: For fun, trim words (rather than individual characters)
// Helper function to detect if a string contains another string
// at a specific position.
// Equivalent to using `str.indexOf(substr, pos) === pos` but *should* be more efficient on longer strings as it can exit early (needs benchmarks to back this up).
function hasSubstringAt(str, substr, pos) {
var idx = 0, len = substr.length;
for (var max = str.length; idx < len; ++idx) {
if ((pos + idx) >= max || str[pos + idx] != substr[idx])
break;
}
return idx === len;
}
function trimWord(str, word) {
var start = 0,
end = str.length,
len = word.length;
while (start < end && hasSubstringAt(str, word, start))
start += word.length;
while (end > start && hasSubstringAt(str, word, end - len))
end -= word.length
return (start > 0 || end < str.length) ? str.substring(start, end) : str;
}
// Usage:
trimWord('blahrealmessageblah', 'blah');
If I understood well, you want to remove a specific character only if it is at the beginning or at the end of the string (ex: ||fo||oo|||| should become foo||oo). You can create an ad hoc function as follows:
function trimChar(string, charToRemove) {
while(string.charAt(0)==charToRemove) {
string = string.substring(1);
}
while(string.charAt(string.length-1)==charToRemove) {
string = string.substring(0,string.length-1);
}
return string;
}
I tested this function with the code below:
var str = "|f|oo||";
$( "#original" ).html( "Original String: '" + str + "'" );
$( "#trimmed" ).html( "Trimmed: '" + trimChar(str, "|") + "'" );
You can use a regular expression such as:
var x = "|f|oo||";
var y = x.replace(/^\|+|\|+$/g, "");
alert(y); // f|oo
UPDATE:
Should you wish to generalize this into a function, you can do the following:
var escapeRegExp = function(strToEscape) {
// Escape special characters for use in a regular expression
return strToEscape.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
};
var trimChar = function(origString, charToTrim) {
charToTrim = escapeRegExp(charToTrim);
var regEx = new RegExp("^[" + charToTrim + "]+|[" + charToTrim + "]+$", "g");
return origString.replace(regEx, "");
};
var x = "|f|oo||";
var y = trimChar(x, "|");
alert(y); // f|oo
A regex-less version which is easy on the eye:
const trim = (str, chars) => str.split(chars).filter(Boolean).join(chars);
For use cases where we're certain that there's no repetition of the chars off the edges.
to keep this question up to date:
here is an approach i'd choose over the regex function using the ES6 spread operator.
function trimByChar(string, character) {
const first = [...string].findIndex(char => char !== character);
const last = [...string].reverse().findIndex(char => char !== character);
return string.substring(first, string.length - last);
}
Improved version after #fabian 's comment (can handle strings containing the same character only)
function trimByChar1(string, character) {
const arr = Array.from(string);
const first = arr.findIndex(char => char !== character);
const last = arr.reverse().findIndex(char => char !== character);
return (first === -1 && last === -1) ? '' : string.substring(first, string.length - last);
}
This can trim several characters at a time:
function trimChars (str, c) {
var re = new RegExp("^[" + c + "]+|[" + c + "]+$", "g");
return str.replace(re,"");
}
var x = "|f|oo||";
x = trimChars(x, '|'); // f|oo
var y = "..++|f|oo||++..";
y = trimChars(y, '|.+'); // f|oo
var z = "\\f|oo\\"; // \f|oo\
// For backslash, remember to double-escape:
z = trimChars(z, "\\\\"); // f|oo
For use in your own script and if you don't mind changing the prototype, this can be a convenient "hack":
String.prototype.trimChars = function (c) {
var re = new RegExp("^[" + c + "]+|[" + c + "]+$", "g");
return this.replace(re,"");
}
var x = "|f|oo||";
x = x.trimChars('|'); // f|oo
Since I use the trimChars function extensively in one of my scripts, I prefer this solution. But there are potential issues with modifying an object's prototype.
If you define these functions in your program, your strings will have an upgraded version of trim that can trim all given characters:
String.prototype.trimLeft = function(charlist) {
if (charlist === undefined)
charlist = "\s";
return this.replace(new RegExp("^[" + charlist + "]+"), "");
};
String.prototype.trim = function(charlist) {
return this.trimLeft(charlist).trimRight(charlist);
};
String.prototype.trimRight = function(charlist) {
if (charlist === undefined)
charlist = "\s";
return this.replace(new RegExp("[" + charlist + "]+$"), "");
};
var withChars = "/-center-/"
var withoutChars = withChars.trim("/-")
document.write(withoutChars)
Source
https://www.sitepoint.com/trimming-strings-in-javascript/
const trim = (str, char) => {
let i = 0;
let j = str.length-1;
while (str[i] === char) i++;
while (str[j] === char) j--;
return str.slice(i,j+1);
}
console.log(trim('|f|oo|', '|')); // f|oo
Non-regex solution.
Two pointers: i (beginning) & j (end).
Only move pointers if they match char and stop when they don't.
Return remaining string.
I would suggest looking at lodash and how they implemented the trim function.
See Lodash Trim for the documentation and the source to see the exact code that does the trimming.
I know this does not provide an exact answer your question, but I think it's good to set a reference to a library on such a question since others might find it useful.
This one trims all leading and trailing delimeters
const trim = (str, delimiter) => {
const pattern = `[^\\${delimiter}]`;
const start = str.search(pattern);
const stop = str.length - str.split('').reverse().join('').search(pattern);
return str.substring(start, stop);
}
const test = '||2|aaaa12bb3ccc|||||';
console.log(trim(test, '|')); // 2|aaaa12bb3ccc
I like the solution from #Pho3niX83...
Let's extend it with "word" instead of "char"...
function trimWord(_string, _word) {
var splitted = _string.split(_word);
while (splitted.length && splitted[0] === "") {
splitted.shift();
}
while (splitted.length && splitted[splitted.length - 1] === "") {
splitted.pop();
}
return splitted.join(_word);
};
The best way to resolve this task is (similar with PHP trim function):
function trim( str, charlist ) {
if ( typeof charlist == 'undefined' ) {
charlist = '\\s';
}
var pattern = '^[' + charlist + ']*(.*?)[' + charlist + ']*$';
return str.replace( new RegExp( pattern ) , '$1' )
}
document.getElementById( 'run' ).onclick = function() {
document.getElementById( 'result' ).value =
trim( document.getElementById( 'input' ).value,
document.getElementById( 'charlist' ).value);
}
<div>
<label for="input">Text to trim:</label><br>
<input id="input" type="text" placeholder="Text to trim" value="dfstextfsd"><br>
<label for="charlist">Charlist:</label><br>
<input id="charlist" type="text" placeholder="Charlist" value="dfs"><br>
<label for="result">Result:</label><br>
<input id="result" type="text" placeholder="Result" disabled><br>
<button type="button" id="run">Trim it!</button>
</div>
P.S.: why i posted my answer, when most people already done it before? Because i found "the best" mistake in all of there answers: all used the '+' meta instead of '*', 'cause trim must remove chars IF THEY ARE IN START AND/OR END, but it return original string in else case.
Another version to use regular expression.
No or(|) used and no global(g) used.
function escapeRegexp(s) {
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
function trimSpecific(value, find) {
const find2 = escapeRegexp(find);
return value.replace(new RegExp(`^[${find2}]*(.*?)[${find2}]*$`), '$1')
}
console.log(trimSpecific('"a"b"', '"') === 'a"b');
console.log(trimSpecific('""ab"""', '"') === 'ab');
console.log(trimSpecific('"', '"') === '');
console.log(trimSpecific('"a', '"') === 'a');
console.log(trimSpecific('a"', '"') === 'a');
console.log(trimSpecific('[a]', '[]') === 'a');
console.log(trimSpecific('{[a]}', '[{}]') === 'a');
expanding on #leaf 's answer, here's one that can take multiple characters:
var trim = function (s, t) {
var tr, sr
tr = t.split('').map(e => `\\\\${e}`).join('')
sr = s.replace(new RegExp(`^[${tr}]+|[${tr}]+$`, 'g'), '')
return sr
}
function trim(text, val) {
return text.replace(new RegExp('^'+val+'+|'+val+'+$','g'), '');
}
"|Howdy".replace(new RegExp("^\\|"),"");
(note the double escaping. \\ needed, to have an actually single slash in the string, that then leads to escaping of | in the regExp).
Only few characters need regExp-Escaping., among them the pipe operator.
const special = ':;"<>?/!`~##$%^&*()+=-_ '.split("");
const trim = (input) => {
const inTrim = (str) => {
const spStr = str.split("");
let deleteTill = 0;
let startChar = spStr[deleteTill];
while (special.some((s) => s === startChar)) {
deleteTill++;
if (deleteTill <= spStr.length) {
startChar = spStr[deleteTill];
} else {
deleteTill--;
break;
}
}
spStr.splice(0, deleteTill);
return spStr.join("");
};
input = inTrim(input);
input = inTrim(input.split("").reverse().join("")).split("").reverse().join("");
return input;
};
alert(trim('##This is what I use$%'));
String.prototype.TrimStart = function (n) {
if (this.charAt(0) == n)
return this.substr(1);
};
String.prototype.TrimEnd = function (n) {
if (this.slice(-1) == n)
return this.slice(0, -1);
};
To my knowledge, jQuery doesnt have a built in function the method your are asking about.
With javascript however, you can just use replace to change the content of your string:
x.replace(/|/i, ""));
This will replace all occurences of | with nothing.
try:
console.log(x.replace(/\|/g,''));
Try this method:
var a = "anan güzel mi?";
if (a.endsWith("?")) a = a.slice(0, -1);
document.body.innerHTML = a;

Remove all occurrences except last?

I want to remove all occurrences of substring = . in a string except the last one.
E.G:
1.2.3.4
should become:
123.4
You can use regex with positive look ahead,
"1.2.3.4".replace(/[.](?=.*[.])/g, "");
2-liner:
function removeAllButLast(string, token) {
/* Requires STRING not contain TOKEN */
var parts = string.split(token);
return parts.slice(0,-1).join('') + token + parts.slice(-1)
}
Alternative version without the requirement on the string argument:
function removeAllButLast(string, token) {
var parts = string.split(token);
if (parts[1]===undefined)
return string;
else
return parts.slice(0,-1).join('') + token + parts.slice(-1)
}
Demo:
> removeAllButLast('a.b.c.d', '.')
"abc.d"
The following one-liner is a regular expression that takes advantage of the fact that the * character is greedy, and that replace will leave the string alone if no match is found. It works by matching [longest string including dots][dot] and leaving [rest of string], and if a match is found it strips all '.'s from it:
'a.b.c.d'.replace(/(.*)\./, x => x.replace(/\./g,'')+'.')
(If your string contains newlines, you will have to use [.\n] rather than naked .s)
You can do something like this:
var str = '1.2.3.4';
var last = str.lastIndexOf('.');
var butLast = str.substring(0, last).replace(/\./g, '');
var res = butLast + str.substring(last);
Live example:
http://jsfiddle.net/qwjaW/
You could take a positive lookahead (for keeping the last dot, if any) and replace the first coming dots.
var string = '1.2.3.4';
console.log(string.replace(/\.(?=.*\.)/g, ''));
A replaceAllButLast function is more useful than a removeAllButLast function. When you want to remove just replace with an empty string:
function replaceAllButLast(str, pOld, pNew) {
var parts = str.split(pOld)
if (parts.length === 1) return str
return parts.slice(0, -1).join(pNew) + pOld + parts.slice(-1)
}
var test = 'hello there hello there hello there'
test = replaceAllButLast(test, ' there', '')
console.log(test) // hello hello hello there
Found a much better way of doing this. Here is replaceAllButLast and appendAllButLast as they should be done. The latter does a replace whilst preserving the original match. To remove, just replace with an empty string.
var str = "hello there hello there hello there"
function replaceAllButLast(str, regex, replace) {
var reg = new RegExp(regex, 'g')
return str.replace(reg, function(match, offset, str) {
var follow = str.slice(offset);
var isLast = follow.match(reg).length == 1;
return (isLast) ? match : replace
})
}
function appendAllButLast(str, regex, append) {
var reg = new RegExp(regex, 'g')
return str.replace(reg, function(match, offset, str) {
var follow = str.slice(offset);
var isLast = follow.match(reg).length == 1;
return (isLast) ? match : match + append
})
}
var replaced = replaceAllButLast(str, / there/, ' world')
console.log(replaced)
var appended = appendAllButLast(str, / there/, ' fred')
console.log(appended)
Thanks to #leaf for these masterpieces which he gave here.
You could reverse the string, remove all occurrences of substring except the first, and reverse it again to get what you want.
function formatString() {
var arr = ('1.2.3.4').split('.');
var arrLen = arr.length-1;
var outputString = '.' + arr[arrLen];
for (var i=arr.length-2; i >= 0; i--) {
outputString = arr[i]+outputString;
}
alert(outputString);
}
See it in action here: http://jsbin.com/izebay
var s='1.2.3.4';
s=s.split('.');
s.splice(s.length-1,0,'.');
s.join('');
123.4

Categories

Resources