Javascript regular expression: remove first and last slash - javascript

I have these strings in javascript:
/banking/bonifici/italia
/banking/bonifici/italia/
and I would like to remove the first and last slash if it's exists.
I tried ^\/(.+)\/?$ but it doesn't work.
Reading some post in stackoverflow I found that php has trim function and I could use his javascript translation (http://phpjs.org/functions/trim:566) but I would prefer a "simple" regular expression.

return theString.replace(/^\/|\/$/g, '');
"Replace all (/.../g) leading slash (^\/) or (|) trailing slash (\/$) with an empty string."

There's no real reason to use a regex here, string functions will work fine:
var string = "/banking/bonifici/italia/";
if (string.charAt(0) == "/") string = string.substr(1);
if (string.charAt(string.length - 1) == "/") string = string.substr(0, string.length - 1);
// string => "banking/bonifici/italia"
See this in action on jsFiddle.
References:
String.substr
String.charAt

In case if using RegExp is not an option, or you have to handle corner cases while working with URLs (such as double/triple slashes or empty lines without complex replacements), or utilizing additional processing, here's a less obvious, but more functional-style solution:
const urls = [
'//some/link///to/the/resource/',
'/root',
'/something/else',
];
const trimmedUrls = urls.map(url => url.split('/').filter(x => x).join('/'));
console.log(trimmedUrls);
In this snippet filter() function can implement more complex logic than just filtering empty strings (which is default behavior).
Word of warning - this is not as fast as other snippets here.

One liner, no regex, handles multiple occurences
const trimSlashes = str => str.split('/').filter(v => v !== '').join('/');
console.log(trimSlashes('/some/path/foo/bar///')); // "some/path/foo/bar"

Just in case that someone needs a premature optimization here...
http://jsperf.com/remove-leading-and-trailing-slashes/5
var path = '///foo/is/not/equal/to/bar///'
var count = path.length - 1
var index = 0
while (path.charCodeAt(index) === 47 && ++index);
while (path.charCodeAt(count) === 47 && --count);
path = path.slice(index, count + 1)

you can check with str.startsWith and str.endsWith
then substr if exist
var str= "/aaa/bbb/";
var str= str.startsWith('/') ? str.substr(1) : str;
var str= str.endsWith('/') ? str.substr(0,str.length - 1) : str;
or you can write custom function
trimSlashes('/aaa/bbb/');
function trimSlashes(str){
str= str.startsWith('/') ? str.substr(1) : str;
str= str.endsWith('/') ? str.substr(0,str.length - 1) : str;
return str;
}

Related

JavaScript remove a character from a string and remove the previous character

How do I remove a character from a string and remove the previous character as well?
Example:
"ABCXDEXFGHXIJK"
I want to split the string by "X" and remove the previous character which returns
"ABDFGIJK" // CX, EX, HX are removed
I found this thread but it removes everything before rather than a specific amount of characters: How to remove part of a string before a ":" in javascript?
I can run a for loop but I was wondering if there was a better/simpler way to achieve this
const remove = function(str){
for(let i = 0; i < str.length; i++){
if(str[i] === "X") str = str.slice(0, i - 1) + str.slice(i + 1);
}
return str
}
console.log(remove("ABCXDEXFGHXIJK")) // ABDFGIJK
You can use String.prototype.replace and regex.
"ABCXDEXFGHXIJK".replace(/.X/g, '')
The g at the end is to replace every occurrence of .X. You can use replaceAll as well, but it has less support.
"ABCXDEXFGHXIJK".replaceAll(/.X/g, '')
If you want it to be case insensitive, use the i flag as well.
"ABCXDEXFGHXIJK".replace(/.x/gi, '')
The simplest way is to use a regular expression inside replace.
"ABCXDEXFGHXIJK".replace(/.X/g, "")
.X means "match the combination of X and any single character before it, g flag after the expression body repeats the process globally (instead of doing it once).
While not the most computationally efficient, you could use the following one-liner that may meet your definition of "a better/simpler way to achieve this":
const remove = str => str.split("X").map((ele, idx) => idx !== str.split("X").length - 1 ? ele.slice(0, ele.length - 1) : ele).join("");
console.log(remove("ABCXDEXFGHXIJK"));
Maybe you can use recursion.
function removeChar(str, char){
const index = str.indexOf(char);
if(index < 0) return str;
// removes 2 characters from string
return removeChar(str.split('').splice(index - 2, index).join());
}
Try this way (Descriptive comments are added in the below code snippet itself) :
// Input string
const str = "ABCXDEXFGHXIJK";
// split the input string based on 'X' and then remove the last item from each element by using String.slice() method.
const splittedStrArr = str.split('X').map(item => item = item.slice(0, -1));
// Output by joining the modified array elements.
console.log(splittedStr.join(''))
By using RegEx :
// Input string
const str = "ABCXDEXFGHXIJK";
// Replace the input string by matching the 'X' and one character before that with an empty string.
const modifiedStr = str.replace(/.X/g, "")
// Output
console.log(modifiedStr)

JavaScript RegExp - find all prefixes up to a certain character

I have a string which is composed of terms separated by slashes ('/'), for example:
ab/c/def
I want to find all the prefixes of this string up to an occurrence of a slash or end of string, i.e. for the above example I expect to get:
ab
ab/c
ab/c/def
I've tried a regex like this: /^(.*)[\/$]/, but it returns a single match - ab/c/ with the parenthesized result ab/c, accordingly.
EDIT :
I know this can be done quite easily using split, I am looking specifically for a solution using RegExp.
NO, you can't do that with a pure regex.
Why? Because you need substrings starting at one and the same location in the string, while regex matches non-overlapping chunks of text and then advances its index to search for another match.
OK, what about capturing groups? They are only helpful if you know how many /-separated chunks you have in the input string. You could then use
var s = 'ab/c/def'; // There are exact 3 parts
console.log(/^(([^\/]+)\/[^\/]+)\/[^\/]+$/.exec(s));
// => [ "ab/c/def", "ab/c", "ab" ]
However, it is unlikely you know that many details about your input string.
You may use the following code rather than a regex:
var s = 'ab/c/def';
var chunks = s.split('/');
var res = [];
for(var i=0;i<chunks.length;i++) {
res.length > 0 ? res.push(chunks.slice(0,i).join('/')+'/'+chunks[i]) : res.push(chunks[i]);
}
console.log(res);
First, you can split the string with /. Then, iterate through the elements and build the res array.
I do not think a regular expression is what you are after. A simple split and loop over the array can give you the result.
var str = "ab/c/def";
var result = str.split("/").reduce(function(a,s,i){
var last = a[i-1] ? a[i-1] + "/" : "";
a.push(last + s);
return a;
}, []);
console.log(result);
or another way
var str = "ab/c/def",
result = [],
parts=str.split("/");
while(parts.length){
console.log(parts);
result.unshift(parts.join("/"));
parts.pop();
}
console.log(result);
Plenty of other ways to do it.
You can't do it with a RegEx in javascript but you can split parts and join them respectively together:
var array = "ab/c/def".split('/'), newArray = [], key = 0;
while (value = array[key++]) {
newArray.push(key == 1 ? value : newArray[newArray.length - 1] + "/" + value)
}
console.log(newArray);
May be like this
var str = "ab/c/def",
result = str.match(/.+?(?=\/|$)/g)
.map((e,i,a) => a[i-1] ? a[i] = a[i-1] + e : e);
console.log(result);
Couldn't you just split the string on the separator character?
var result = 'ab/c/def'.split(/\//g);

Javascript regex to replace "split"

I would like to use Javascript Regex instead of split.
Here is the example string:
var str = "123:foo";
The current method calls:
str.split(":")[1]
This will return "foo", but it raises an Error when given a bad string that doesn't have a :.
So this would raise an error:
var str = "fooblah";
In the case of "fooblah" I'd like to just return an empty string.
This should be pretty simple, but went looking for it, and couldn't figure it out. Thank you in advance.
Remove the part up to and including the colon (or the end of the string, if there's no colon):
"123:foo".replace(/.*?(:|$)/, '') // "foo"
"foobar" .replace(/.*?(:|$)/, '') // ""
How this regexp works:
.* Grab everything
? non-greedily
( until we come to
: a colon
| or
$ the end of the string
)
A regex won't help you. Your error likely arises from trying to use undefined later. Instead, check the length of the split first.
var arr = str.split(':');
if (arr.length < 2) {
// Do something to handle a bad string
} else {
var match = arr[1];
...
}
Here's what I've always used, with different variations; this is just a simple version of it:
function split(str, d) {
var op = "";
if(str.indexOf(d) > 0) {
op = str.split(d);
}
return(op);
}
Fairly simple, either returns an array or an empty string.
var str1 = "123:foo", str2 = "fooblah";
var res = function (s) {
return /:/.test(s) && s.replace(/.*(?=:):/, "") || ""
};
console.log(res(str1), res(str2))
Here is a solution using a single regex, with the part you want in the capturing group:
^[^:]*:([^:]+)

How to remove the end of a string, starting from a given pattern?

Let's say I have a string like this:
var str = "/abcd/efgh/ijkl/xxx-1/xxx-2";
How do I, using Javascript and/or jQuery, remove the part of str starting with xxx, till the end of str?
str.substring( 0, str.indexOf( "xxx" ) );
Just:
s.substring(0, s.indexOf("xxx"))
A safer version handling invalid input and lack of matching patterns would be:
function trump(str, pattern) {
var trumped = ""; // default return for invalid string and pattern
if (str && str.length) {
trumped = str;
if (pattern && pattern.length) {
var idx = str.indexOf(pattern);
if (idx != -1) {
trumped = str.substring(0, idx);
}
}
}
return (trumped);
}
which you'd call with:
var s = trump("/abcd/efgh/ijkl/xxx-1/xxx-2", "xxx");
Try using string.slice(start, end):
If you know the exact number of characters you want to remove, from your example:
var str = "/abcd/efgh/ijkl/xxx-1/xxx-2";
new_str = str.slice(0, -11);
This would result in str_new == '/abcd/efgh/ijkl/'
Why this is useful:
If the 'xxx' refers to any string (as the OP said), i.e: 'abc', '1k3', etc, and you do not know beforehand what they could be (i.e: Not constant), the accepted answers, as well as most of the others will not work.
Try this:
str.substring(0, str.indexOf("xxx"));
indexOf will find the position of xxx, and substring will cut out the piece you want.
This will take everything from the start of the string to the beginning of xxx.
str.substring(0,str.indexOf("xxx"));

Remove all dots except the first one from a string

Given a string
'1.2.3.4.5'
I would like to get this output
'1.2345'
(In case there are no dots in the string, the string should be returned unchanged.)
I wrote this
function process( input ) {
var index = input.indexOf( '.' );
if ( index > -1 ) {
input = input.substr( 0, index + 1 ) +
input.slice( index ).replace( /\./g, '' );
}
return input;
}
Live demo: http://jsfiddle.net/EDTNK/1/
It works but I was hoping for a slightly more elegant solution...
There is a pretty short solution (assuming input is your string):
var output = input.split('.');
output = output.shift() + '.' + output.join('');
If input is "1.2.3.4", then output will be equal to "1.234".
See this jsfiddle for a proof. Of course you can enclose it in a function, if you find it necessary.
EDIT:
Taking into account your additional requirement (to not modify the output if there is no dot found), the solution could look like this:
var output = input.split('.');
output = output.shift() + (output.length ? '.' + output.join('') : '');
which will leave eg. "1234" (no dot found) unchanged. See this jsfiddle for updated code.
It would be a lot easier with reg exp if browsers supported look behinds.
One way with a regular expression:
function process( str ) {
return str.replace( /^([^.]*\.)(.*)$/, function ( a, b, c ) {
return b + c.replace( /\./g, '' );
});
}
You can try something like this:
str = str.replace(/\./,"#").replace(/\./g,"").replace(/#/,".");
But you have to be sure that the character # is not used in the string; or replace it accordingly.
Or this, without the above limitation:
str = str.replace(/^(.*?\.)(.*)$/, function($0, $1, $2) {
return $1 + $2.replace(/\./g,"");
});
You could also do something like this, i also don't know if this is "simpler", but it uses just indexOf, replace and substr.
var str = "7.8.9.2.3";
var strBak = str;
var firstDot = str.indexOf(".");
str = str.replace(/\./g,"");
str = str.substr(0,firstDot)+"."+str.substr(1,str.length-1);
document.write(str);
Shai.
Here is another approach:
function process(input) {
var n = 0;
return input.replace(/\./g, function() { return n++ > 0 ? '' : '.'; });
}
But one could say that this is based on side effects and therefore not really elegant.
This isn't necessarily more elegant, but it's another way to skin the cat:
var process = function (input) {
var output = input;
if (typeof input === 'string' && input !== '') {
input = input.split('.');
if (input.length > 1) {
output = [input.shift(), input.join('')].join('.');
}
}
return output;
};
Not sure what is supposed to happen if "." is the first character, I'd check for -1 in indexOf, also if you use substr once might as well use it twice.
if ( index != -1 ) {
input = input.substr( 0, index + 1 ) + input.substr(index + 1).replace( /\./g, '' );
}
var i = s.indexOf(".");
var result = s.substr(0, i+1) + s.substr(i+1).replace(/\./g, "");
Somewhat tricky. Works using the fact that indexOf returns -1 if the item is not found.
Trying to keep this as short and readable as possible, you can do the following:
JavaScript
var match = string.match(/^[^.]*\.|[^.]+/g);
string = match ? match.join('') : string;
Requires a second line of code, because if match() returns null, we'll get an exception trying to call join() on null. (Improvements welcome.)
Objective-J / Cappuccino (superset of JavaScript)
string = [string.match(/^[^.]*\.|[^.]+/g) componentsJoinedByString:''] || string;
Can do it in a single line, because its selectors (such as componentsJoinedByString:) simply return null when sent to a null value, rather than throwing an exception.
As for the regular expression, I'm matching all substrings consisting of either (a) the start of the string + any potential number of non-dot characters + a dot, or (b) any existing number of non-dot characters. When we join all matches back together, we have essentially removed any dot except the first.
var input = '14.1.2';
reversed = input.split("").reverse().join("");
reversed = reversed.replace(\.(?=.*\.), '' );
input = reversed.split("").reverse().join("");
Based on #Tadek's answer above. This function takes other locales into consideration.
For example, some locales will use a comma for the decimal separator and a period for the thousand separator (e.g. -451.161,432e-12).
First we convert anything other than 1) numbers; 2) negative sign; 3) exponent sign into a period ("-451.161.432e-12").
Next we split by period (["-451", "161", "432e-12"]) and pop out the right-most value ("432e-12"), then join with the rest ("-451161.432e-12")
(Note that I'm tossing out the thousand separators, but those could easily be added in the join step (.join(','))
var ensureDecimalSeparatorIsPeriod = function (value) {
var numericString = value.toString();
var splitByDecimal = numericString.replace(/[^\d.e-]/g, '.').split('.');
if (splitByDecimal.length < 2) {
return numericString;
}
var rightOfDecimalPlace = splitByDecimal.pop();
return splitByDecimal.join('') + '.' + rightOfDecimalPlace;
};
let str = "12.1223....1322311..";
let finStr = str.replace(/(\d*.)(.*)/, '$1') + str.replace(/(\d*.)(.*)/, '$2').replace(/\./g,'');
console.log(finStr)
const [integer, ...decimals] = '233.423.3.32.23.244.14...23'.split('.');
const result = [integer, decimals.join('')].join('.')
Same solution offered but using the spread operator.
It's a matter of opinion but I think it improves readability.

Categories

Resources