Substring from the end in generic way in javascript - javascript

Assume we have such strings.
const del = 'Deleted'
const str1 = 'clean.Deleted'
const str2 = 'get.clean.Deleted'
const str3 = 'cl.Deleted'
And I need return every time str1, str2,str3 without .Deleted
It is work for me:
any_string.substr(0, (any_string.length - del.length-1))
Do we have a more generic way?

If .Deleted is always .Deleted, then string.replace
const newString = oldString.replace('.Deleted', '')
You can replace that with RegExp if you only want .Deleted that happens at the end.
const newString = oldString.replace(/\.Deleted$/, '')

To achieve expected result, use slice with negative value for slicing from last(.Deleted length is 8, so use -8)
str.slice('.Deleted',-8)
JS:
const del = 'Deleted'
const str1 = 'clean.Deleted'
const str2 = 'get.clean.Deleted'
const str3 = 'cl.Deleted'
console.log(str1.slice('.Deleted',-8))
console.log(str2.slice('.Deleted',-8))
console.log(str3.slice('.Deleted',-8))
Note: This solution works only if the .Deleted is always at the last part of the string

Related

Convert End Quote to Apostrophe Javascript

The below two strings have different apostrophes. I am pretty stumped on how to convert them so that they are the same style (both are either slanted or both are either straight up and down). I have tried everything from enclosing it in `${}`` to regex expressions to remove and replace. I am not sure how it is being stored like this but when I try to search for string1 inside of string2 it doesn't recognize the index because (I believe) of the mismatch apostrophe. Has anyone run into this before?
//let textData = Father’s
//let itemData = Father's Day
const newData = currData.filter(item => {
let itemData = `${item.activityName.toUpperCase()}`;
let textData = `${text.toUpperCase()}`; //coming in slanted
let newItemData = itemData.replace(/"/g, "'");
let newTextData = textData.replace(/"/g, "'");
return newItemData.indexOf(newTextData) > -1;
});
first of all, your code won't run because you are not wrapping your string variables with ", ' or `, depending on the case.
if your string has ' you can use " or ` like this:
"Hello, I'm a dev"
or
"Hello, I`m a dev"
but you can not mix them if you have the same symbol, so this is not allowed:
'Hello, I`m a dev'
here you have a working example of your strings wrapped correctly and also replacing the values to match the strings.
note: please look that the index in this case is 0 because the whole string that we are looking matches from the 0 index to the length of the response1.
also I added a case if you want to get the partial string from string2 based on the match of string1
let string1 = "FATHER’S"
let string2 = "FATHER'S DAY: FOR THE FIXER"
const regex = /’|'/;
const replacer = "'";
let response1 = string1.replace(regex, replacer);
let response2 = string2.replace(regex, replacer);
console.log(response1);
console.log(response2);
console.log("this is your index --> ", response2.indexOf(response1));
console.log("string 2 without string 1 -->", response2.slice(response2.indexOf(response1) + response1.length, response2.length))
You could do a search using a regex, allowing for whatever apostrophe variations you expect:
let string1 = "FATHER’S"
let string2 = "FATHER'S DAY: FOR THE FIXER"
const regex = string1.split(/['’"`]/).join("['’\"`]")
//console.log(regex);
const r = new RegExp(regex)
console.log(string2.search(r)); //comes back as 0

Matching function name and arguments using regex

I have some strings in the following pattern
'walkPath(left, down, left)'
To extract the function name alone, and the arguments in an another array, i used those regular expressions:
const str = 'walkPath(left, down, left)'
const functionNameRegex = /[a-zA-Z]*(?=\()/
console.log(str.match(functionNameRegex)) //outputs ['walkPath'] ✅✅
const argsRegex = /(?![a-zA-Z])([^,)]+)/g
console.log(str.match(argsRegex)) //outputs [ '(left', ' down', ' left' ]
the first one worked fine. In the second regex, the '(' from from '(left' should be excluded, so it should be 'left'
Try this one:
/(?<=\((?:\s*\w+\s*,)*\s*)\w+/g
const str = 'walkPath(left, down, left)'
const functionNameRegex = /[a-zA-Z]*(?=\()/
console.log(str.match(functionNameRegex))
const argsRegex = /(?<=\((?:\s*\w+\s*,)*\s*)\w+/g
console.log(str.match(argsRegex))
It is not very restricted, if you really want to be safe, you can try:
/(?<=\w+\s*\((?:\s*\w+\s*,\s*)*\s*)\w+(?=\s*(?:\s*,\s*\w+\s*)*\))/g
Use this regular expression for getting the arguments:
const argsRegex = /\(\s*([^)]+?)\s*\)/
For getting the arguments in an array:
const str = 'walkPath(left, down, left)'
const argsRegex = /\(\s*([^)]+?)\s*\)/
let res = str.match(argsRegex)
let args = res[1].split(", ")

Regex for URL/String - If protocol return false

Trying to create a regex in which the string should not start with http(s)://, http(s)://www. Rest of the string can be anything.
I used this regeg but its return true if we have http://
^(http://www.|https://www.|http://|https://)?[a-z0-9]+([-.]{1}[a-z0-9]+)*.[a-z]{2,5}(:[0-9]{1,5})?(/.*)?$
Another one I tried is
var re = new RegExp("(http|https|ftp)://");
var str = "http://xxxx.com";
var match = re.test(str);
console.log(match);
this one is also returning true.
Demo here
let re = /(http|https|ftp):///;
let url = 'xxxx.xxxx.xxxx'; // this is valid but test returns false
let url2 = 'https://www.xxzx.com/xxx.aspx'; // this should fail as there is https://www in url
console.log(re.test(url)); //
console.log(re.test(url2)); //
Is this possible with regex?
You need to use negative lookahead in your regex to discard strings starting with protocols like http or https or ftp. You can use this regex,
^(?!(?:ftp|https?):\/\/(www\.)?).+$
Regex Demo
JS Demo,
const arr = ['xxxx.xxxx.xxxx','ftp://www.xxzx.com/xxx.aspx','https://www.xxzx.com/xxx.aspx','http://xxxx.com','https://xxzx.com/xxx.aspx','http://www.xxxx.com']
arr.forEach(s => console.log(s + " --> " + /^(?!(?:ftp|https?):\/\/(www\.)?).+$/.test(s)))
It's probably possible to do with regexes, but unless you have to use a regex, you should use the URL class:
let HTTP_URL = 'https://www.xxzx.com/xxx.aspx'
let HTTPS_URL = 'https://www.xxzx.com/xxx.aspx'
let FTP_URL = 'ftp://www.xxzx.com/xxx.aspx'
let GOOD_PROTOCOL = 'mysql://www.xxzx.com/xxx.aspx'
let GOOD_INPUT = '129.123.12.123'
function test_url(url) {
let bad_protocols = ['http:', 'https:', 'ftp:']
try {
var parsed = new URL(url)
} catch {
return true
}
return (!bad_protocols.contains(parsed.protocol))
}
test_url(HTTP_URL) //false
test_url(HTTPS_URL) //false
test_url(FTP_URL) //false
test_url(GOOD_PROTOCOL) //true
test_url(GOOD_INPUT) //true
If you're just trying to negate that regex:
function doesMatch(string) {
return !/^http(s):\/\/(?:www)?/.test(string);
}
[
'https://www.xxzx.com/xxx.aspx',
'http://www.xxxx.com',
'https://xxxx.com',
'http://xxxx.com',
'https://aaaa.com',
'aaaa.com'
].forEach(s => console.log(doesMatch(s)));
In your example code, re.test(url) returns false , because there is no presence of http or https in that string.
In url2 (ie..'https://www.xxzx.com/xxx.aspx') , there is a presence of https so it is returning true.
This expression might also work, it would allow your desired input and fails all other URLs, and you can also simply add to its char list, what else might be undesired to start:
^([^http|s|ftp|www|\/\/|])*
Pass
xxxx.xxxx.xxxx
Fail
ftp://www.xxzx.com/xxx.aspx
https://www.xxzx.com/xxx.aspx
http://xxxx.com
https://xxzx.com/xxx.aspx
http://www.xxxx.com
//www.xxxx.com
You can test/modify/change it in this link.
RegEx Descriptive Graph
This graph shows how the expression would work and you can visualize other expressions in this link:
Performance Test
This JavaScript snippet shows the performance of that expression using a simple 1-million times for loop.
const repeat = 1000000;
const start = Date.now();
for (var i = repeat; i >= 0; i--) {
const string = 'xxxx.xxxx.xxxx';
const regex = /(^([^http|s|ftp|www|\/\/|])*)/gm;
var match = string.replace(regex, "$1");
}
const end = Date.now() - start;
console.log("YAAAY! \"" + match + "\" is a match 💚💚💚 ");
console.log(end / 1000 + " is the runtime of " + repeat + " times benchmark test. 😳 ");

How to replace a string using regexp in JavaScript

I want to filter a given string and replace some common words from a given string:
const str ='api/knwl/tests/products';
const str1 = 'api/users';
const str2 = 'api/tests/providers';
I want to filter the words 'api', 'knwl' or 'tests' from a given strings.
I tried somthing with regexp:
/(?!(tests|api|knwl))/g
But it doesn't work. How can I fix this issue? I'm not expert on regexp.
Regex - /(tests|api|knwl)/g;
const str ='api/knwl/tests/products';
const str1 = 'api/users';
const str2 = 'api/tests/providers';
const filterRegex = str.replace(/(tests|api|knwl)/g,''); // replace all occurence of strings (tests,api,knwl) to empty.

How can I replace multiple characters in a string?

I want to create a regex with following logic:
1., If string contains T replace it with space
2., If string contains Z remove Z
I wrote two regex already, but I can't combine them:
string.replace(/\T/g,' ') && string.replace(/\Z/g,'');
EDIT: I want the regex code to be shorter
Doesn't seem this even needs regex. Just 2 chained replacements would do.
var str = '[T] and [Z] but not [T] and [Z]';
var result = str.replace('T',' ').replace('Z','');
console.log(result);
However, a simple replace only replaces the first occurence.
To replace all, regex still comes in handy. By making use of the global g flag.
Note that the characters aren't escaped with \. There's no need.
var str = '[T] and [Z] and another [T] and [Z]';
var result = str.replace(/T/g,' ').replace(/Z/g,'');
console.log(result);
// By using regex we could also ignore lower/upper-case. (the i flag)
// Also, if more than 1 letter needs replacement, a character class [] makes it simple.
var str2 = '(t) or (Ⓣ) and (z) or (Ⓩ). But also uppercase (T) or (Z)';
var result2 = str2.replace(/[tⓉ]/gi,' ').replace(/[zⓏ]/gi,'');
console.log(result2);
But if the intention is to process really big strings, and performance matters?
Then I found out in another challenge that using an unnamed callback function inside 1 regex replace can prove to be faster. When compared to using 2 regex replaces.
Probably because if it's only 1 regex then it only has to process the huge string once.
Example snippet:
console.time('creating big string');
var bigstring = 'TZ-'.repeat(2000000);
console.timeEnd('creating big string');
console.log('bigstring length: '+bigstring.length);
console.time('double replace big string');
var result1 = bigstring.replace(/[t]/gi,'X').replace(/[z]/gi,'Y');
console.timeEnd('double replace big string');
console.time('single replace big string');
var result2 = bigstring.replace(/([t])|([z])/gi, function(m, c1, c2){
if(c1) return 'X'; // if capture group 1 has something
return 'Y';
});
console.timeEnd('single replace big string');
var smallstring = 'TZ-'.repeat(5000);
console.log('smallstring length: '+smallstring.length);
console.time('double replace small string');
var result3 = smallstring.replace(/T/g,'X').replace(/Z/g,'Y');
console.timeEnd('double replace small string');
console.time('single replace small string');
var result4 = smallstring.replace(/(T)|(Z)/g, function(m, c1, c2){
if(c1) return 'X';
return 'Y';
});
console.timeEnd('single replace small string');
Do you look for something like this?
ES6
var key = {
'T': ' ',
'Z': ''
}
"ATAZATA".replace(/[TZ]/g, (char) => key[char] || '');
Vanilla
"ATAZATA".replace(/[TZ]/g,function (char) {return key[char] || ''});
or
"ATAZATA".replace(/[TZ]/g,function (char) {return char==='T'?' ':''});
you can capture both and then decide what to do in the callback:
string.replace(/[TZ]/g,(m => m === 'T' ? '' : ' '));
var string = 'AZorro Tab'
var res = string.replace(/[TZ]/g,(m => m === 'T' ? '' : ' '));
console.log(res)
-- edit --
Using a dict substitution you can also do:
var string = 'AZorro Tab'
var dict = { T : '', Z : ' '}
var re = new RegExp(`[${ Object.keys(dict).join('') }]`,'g')
var res = string.replace(re,(m => dict[m] ) )
console.log(res)
Second Update
I have developed the following function to use in production, perhaps it can help someone else. It's basically a loop of the native's replaceAll Javascript function, it does not make use of regex:
function replaceMultiple(text, characters){
for (const [i, each] of characters.entries()) {
const previousChar = Object.keys(each);
const newChar = Object.values(each);
text = text.replaceAll(previousChar, newChar);
}
return text
}
Usage is very simple:
const text = '#Please send_an_information_pack_to_the_following_address:';
const characters = [
{
"#":""
},
{
"_":" "
},
]
const result = replaceMultiple(text, characters);
console.log(result); //'Please send an information pack to the following address:'
Update
You can now use replaceAll natively.
Outdated Answer
Here is another version using String Prototype. Enjoy!
String.prototype.replaceAll = function(obj) {
let finalString = '';
let word = this;
for (let each of word){
for (const o in obj){
const value = obj[o];
if (each == o){
each = value;
}
}
finalString += each;
}
return finalString;
};
'abc'.replaceAll({'a':'x', 'b':'y'}); //"xyc"

Categories

Resources