JS Match all occurrences of substring in a string - javascript

I have seen this link but my question is different.
javascript regex match all occurrences of substring?
match() function in JS can be used to match a substring in a string.
When I run this code, I got output like this.
let s = 'Hello_HaHaHaHackerRank';
let hacker = s.match('HaHa');
console.log(hacker);
console.log(hacker.index);
console.log(hacker.input);
Output:
["HaHa"]
6
Hello_HaHaHaHackerRank
hacker.index is giving one first occurrence of the pattern. But the string has three times HaHa. One is at index 6, another is at index 8 and another is at index 10.
Can anyone please explain, How can I get the occurrences of all substring?

indexOf has a fromIndex value you can use with a while loop str.indexOf(searchValue[, fromIndex])
let s = 'Hello_HaHaHaHackerRank';
let find = 'HaHa'
let hacker = [];
let i = 0, j=0;
while (~(i = s.indexOf (find,i + find.length))) hacker.push(i);
console.log (hacker)
If you want to include all occurences, don't add the length of the word.
while (~(i = s.indexOf (find,++i))) hacker.push (i)

Try with:
let re = /HaHa/g,
str = "Hello_HaHaHaHackerRank";
while ((match = re.exec(str)) != null) {
console.log("match found at " + match.index);
}

Related

Javascript remove end of a directory in a string [duplicate]

This question already has answers here:
JS remove everything after the last occurrence of a character [duplicate]
(9 answers)
Closed 3 years ago.
I been looking into split(), slice(), substring() but im not sure they can do what i am looking for.
Basically I want to remove the last sub directory of a string for examble:
Computers/Hard-drive/5GB/Brand
I need to be able to remove the Brand out to something like Computers/Hard-drive/5GB
My solution is
var val = directory.split("/");
var result;
val.forEach(function (dir) {
result = result+"/"+dir;
});
console.log(result);
This returns what I want. But I think this is bad code, I think there must be some way of doing this using only one line. What are other ways of doing this?
You have lots of options.
The regular expression approach
The lastIndexOf approach
The split/join approach
Personally I prefer the simplicity and lack of unnecessary intermediate objects that #2 provides.
1. The regular expression approach
...either as shown by CertainPerformance or a version using replace to replace all characters after the last /.
let str = "Computers/Hard-drive/5GB/Brand";
str = str.replace(/\/[^\/]+$/, "");
console.log(str);
This works just fine if there isn't any slash; it just returns the string unchanged.
2. The lastIndexOf version
let str = "Computers/Hard-drive/5GB/Brand";
const index = str.lastIndexOf("/");
str = str.substring(0, index);
console.log(str);
Note that the above assumes there will be a slash. To not make that assumption, you need to add a guard in case index is -1:
let str = "Computers/Hard-drive/5GB/Brand";
let index = str.lastIndexOf("/");
if (index !== -1) {
str = str.substring(0, index);
}
console.log(str);
str = "Computers";
index = str.lastIndexOf("/");
if (index !== -1) {
str = str.substring(0, index);
}
console.log(str);
3. The split and join approach
...as shown by Nina. (Removed mine when I saw hers, which is much more concise without being harder to read.) Note that Nina's implementation also assumes there will be a slash, you'll need to do a check on the result of split (e.g., is it more than one long) to handle the case where there isn't one.
One option is to use a regular expression: match characters until lookahead matches /, followed by non-/ characters, followed by the end of the string:
const str = 'Computers/Hard-drive/5GB/Brand';
const result = str.match(/.*(?=\/[^/]+$)/)[0];
console.log(result);
You can try with String.prototype.lastIndexOf() and String.prototype.substring()
var directory = 'Computers/Hard-drive/5GB/Brand'
var pos = directory.lastIndexOf("/");
var result = directory.substring(0, pos);
console.log(result);
You could split, slice untile the item before the last one and join the array to a string.
var string = 'Computers/Hard-drive/5GB/Brand',
result = string.split('/').slice(0, -1).join('/');
console.log(result);

I need help getting the first n characters of a string up to when a number character starts

I'm working with a string where I need to extract the first n characters up to where numbers begin. What would be the best way to do this as sometimes the string starts with a number: 7EUSA8889er898 I would need to extract 7EUSA But other string examples would be SWFX74849948, I would need to extract SWFX from that string.
Not sure how to do this with regex my limited knowledge is blocking me at this point:
^(\w{4}) that just gets me the first four characters but I don't really have a stopping point as sometimes the string could be somelongstring292894830982 which would require me to get somelongstring
Using \w will match a word character which includes characters and digits and an underscore.
You could match an optional digit [0-9]? from the start of the string ^and then match 1+ times A-Za-z
^[0-9]?[A-Za-z]+
Regex demo
const regex = /^[0-9]?[A-Za-z]+/;
[
"7EUSA8889er898",
"somelongstring292894830982",
"SWFX74849948"
].forEach(s => console.log(s.match(regex)[0]));
Can use this regex code:
(^\d+?[a-zA-Z]+)|(^\d+|[a-zA-Z]+)
I try with exmaple and good worked:
1- somelongstring292894830982 -> somelongstring
2- 7sdfsdf5456 -> 7sdfsdf
3- 875werwer54556 -> 875werwer
If you want to create function where the RegExp is parametrized by n parameter, this would be
function getStr(str,n) {
var pattern = "\\d?\\w{0,"+n+"}";
var reg = new RegExp(pattern);
var result = reg.exec(str);
if(result[0]) return result[0].substr(0,n);
}
There are answers to this but here is another way to do it.
var string1 = '7EUSA8889er898';
var string2 = 'SWFX74849948';
var Extract = function (args) {
var C = args.split(''); // Split string in array
var NI = []; // Store indexes of all numbers
// Loop through list -> if char is a number add its index
C.map(function (I) { return /^\d+$/.test(I) === true ? NI.push(C.indexOf(I)) : ''; });
// Get the items between the first and second occurence of a number
return C.slice(NI[0] === 0 ? NI[0] + 1 : 0, NI[1]).join('');
};
console.log(Extract(string1));
console.log(Extract(string2));
Output
EUSA
SWFX7
Since it's hard to tell what you are trying to match, I'd go with a general regex
^\d?\D+(?=\d)

Remove part of string that contains a tag

I have a variable in JavaScript that holds the below value:
<label>AAA</label>
I need just the AAA. I try to replace the characters but it is failing. Would someone please suggest the best approach?
var company="<label>AAA</label>";// I am getting this value from element
var rx = new RegExp("((\\$|)(([1-9]\\d{0,2}(\\,\\d{3})*|([1-9]\\d*))(\\.\\d{2})))|(\\<)*(\\>)");
var arr = rx.exec(company);
var arr1 = company.match(rx);
if (arr[1] != null) {
var co = arr[1].replace(",", "");
}
}
As you say you need only AAA, consider the below code.
I have taken a substring between the first '>' character in the string company, added 1 to that and the last < character. However, if the company var contains more of such < or >, you could go for a regex approach.
var company="<label>AAA</label>";
alert(company.substring(company.indexOf('>')+1, company.lastIndexOf('<')));

Replace string between second set of [ and ]

I am learning regex, and I got a doubt. Let's consider
var s = "YYYN[1-20]N[]NYY";
Now, I want to replace/insert the '1-8' between [ and ] at its second occurrence.
Then output should be
YYYN[1-20]N[1-8]NYY
For that I had tried using replace and passing a function through it as shown below:
var nth = 0;
s = s.replace(/\[([^)]+)\]/g, function(match, i, original) {
nth++;
return (nth === 1) ? "1-8" : match;
});
alert(s); // But It wont work
I think that regex is not matchIing the string that I am using.
How can I fix it?
You regex \[([^)]+)\] will not match empty square brackets since + requires at least 1 character other than ). I guess you wanted to write \[[^\]]*\].
Here is a fix for your solution:
var s = "YYYN[1-20]N[]NYY";
var nth = 0;
s = s.replace(/\[[^\]]*\]/g, function (match, i, original) {
nth++;
return (nth !== 1) ? "[1-8]" : match;
});
alert(s);
Here is another way of doing it:
var s = "YYYN[1-20]N[]NYY";
var nth = 0;
s = s.replace(/(.*)\[\]/, "$1[1-8]");
alert(s);
The regex (.*)\[\] matches and captures into Group 1 greedily as much text as possible (thus we get the last set of empty []), and then matches empty square brackets. Then we restore the text before [] with $1 backreference and add out string 1-8.
If it’s only two occurences of square brackets, then this will work:
/(.*\[.*?\].*\[).*?(\].*)/
This RegEx has “YYYN[1-20]N[” as the first capturing group and “]NYY” as the second.
I suggest using simple split and join operations:
var s = "YYYN[1-20]N[]NYY";
var arr = s.split(/\[/)
arr[2] = '1-8' + arr[2]
var r = arr.join('[')
//=> YYYN[1-20]N[1-8]NYY
You can use following regex :
var s = "YYYN[1-20]N[]NYY";
var nth = 0;
s = s.replace(/([^[]+\[(?:[^[]+)\][^[]+)\[[^[]+\](.+)/, "$1[1-8]$2");
alert(s);
The first part ([^[]+\[([^[]+)\][^[]+) will match a string contain first sub-string between []. and \[[^[]+\] would be the second one which you want and the last part (.+?) match the rest of your string.

split string based on a symbol

I'm trying to split a string into an array based on the second occurrence of the symbol _
var string = "this_is_my_string";
I want to split the string after the second underscore. The string is not always the same but it always has 2 or more underscores in it. I always need it split on the second underscore.
In the example string above I would need it to be split like this.
var split = [this_is, _my_string];
var string = "this_is_my_string";
var firstUnderscore = string.indexOf('_');
var secondUnderscore = string.indexOf('_', firstUnderscore + 1);
var split = [string.substring(0, secondUnderscore),
string.substring(secondUnderscore)];
Paste it into your browser's console to try it out. No need for a jsFiddle.
var string = "this_is_my_string";
var splitChar = string.indexOf('_', string.indexOf('_') + 1);
var result = [string.substring(0, splitChar),
string.substring(splitChar, string.length)];
This should work.
var str = "this_is_my_string";
var matches = str.match(/(.*?_.*?)(_.*)/); // MAGIC HAPPENS HERE
var firstPart = matches[1]; // this_is
var secondPart = matches[2]; // _my_string
This uses regular expressions to find the first two underscores, and captures the part up to it and the part after it. The first subexpression, (.*?_.*?), says "any number of characters, an underscore, and again any number of characters, keeping the number of characters matched as small as possible, and capture it". The second one, (_.*) means "match an underscore, then any number of characters, as much of them as possible, and capture it". The result of the match function is an array starting with the full matched region, followed by the two captured groups.
I know this post is quite old... but couldn't help but notice that no one provided a working solution. Here's one that works:
String str = "this_is_my_string";
String undScore1 = str.split("_")[0];
String undScore2 = str.split("_")[1];
String bothUndScores = undScore1 + "_" + undScore2 + "_";
String allElse = str.split(bothUndScores)[1];
System.out.println(allElse);
This is assuming you know there will always be at least 2 underscores - "allElse" returns everything after the second occurrence.

Categories