Regex select all after nth occurance of character - javascript

I have a string in the following format and I'm trying to return all the data after the 3rd occurrence of the ':' character as in the example below.
user_name_1, 10:46:36 activity_name_1 : the text to be returned
So far I have the regex \:.* that returns everything after the first occurrence, eg. :46:36 activity_name_1 : the text to be returned
If I modify it to \:{3}.* eg. to look for the 3rd instance, the regex will not return any matches. It looks like it should be a very simple query but nothing I've tried seems to work.
I've already found the following question find value after nth occurence of - using RegEx however in this case they're returning only the next 3 digits after the nth character and not the entire remaining string.

You can use
^(?:[^:]*:){3}\s*(\S.*)
See the regex demo. Details:
^ - start of string
(?:[^:]*:){3} - three occurrences of any zero or more chars other than a : and then a : char
\s* - zero or more whitespaces
(\S.*) - Group 1: a non-whitespace char and then the rest of the line.
See the JavaScript demo:
const text = "user_name_1, 10:46:36 activity_name_1 : the text to be returned";
const match = text.match(/^(?:[^:]*:){3}\s*(\S.*)/)
if (match) {
console.log(match[1])
}

I'd suggest not using regex for this. split() the string by the : character and remove the first two elements of the resulting array.
You can turn the result back in to a string if necessary by using join():
let input = 'user_name_1, 10:46:36 activity_name_1 : the text to be returned : foo : bar';
let arr = input.split(':');
arr.splice(0, 3);
console.log(arr);
let output = arr.join(':').trim();
console.log(output);

Related

regex match not outputting the adjacent matches javascript

i was experimenting on regex in javascript. Then i came across an issue such that let consider string str = "+d+a+", I was trying to output those characters in the string which are surrounded by +, I used str.match(/\+[a-z]\+/ig), so here what I'm expecting is ["+d+","+a+"], but what i got is just ["+d+"], "+a+" is not showing in the output. Why?
.match(/.../g) returns all non-overlapping matches. Your regex requires a + sign on each side. Given your target string:
+d+a+
^^^
^^^
Your matches would have to overlap in the middle in order to return "+a+".
You can use look-ahead and a manual loop to find overlapping matches:
var str = "+d+a+";
var re = /(?=(\+[a-z]\+))/g;
var matches = [], m;
while (m = re.exec(str)) {
matches.push(m[1]);
re.lastIndex++;
}
console.log(matches);
With regex, when a character gets consumed with a match, then it won't count for the next match.
For example, a regex like /aba/g wouldn't find 2 aba's in a string like "ababa".
Because the second "a" was already consumed.
However, that can be overcome by using a positive lookahead (?=...).
Because lookaheads just check what's behind without actually consuming it.
So a regex like /(ab)(?=(a))/g would return 2 capture groups with 'ab' and 'a' for each 'aba'.
But in this case it just needs to be followed by 1 fixed character '+'.
So it can be simplified, because you don't really need capture groups for this one.
Example snippet:
var str = "+a+b+c+";
var matches = str.match(/\+[a-z]+(?=\+)/g).map(function(m){return m + '+'});
console.log(matches);

How to achieve this result using Regex?

Given the input below, what's the regex expression that gives the desired output in javascript? I must achieve this without using a multiline flag.
input
\n
\n
abc def.\n
\n
*\n
\n
desired output (maintain same number of rows but insert = into blank rows)
=\n
=\n
abc def.\n
=\n
*\n
=\n
actual output (using regex /[^a-zA-Z0-9.*]+\n/ replaced with =\n; it somehow removes one of two consecutive `\n`s)
=\n
abc def.=\n
*=\n
You could try a combination of replace functions like so:
str = "\n\nabc def.\n\n*\n\n";
str = str.replace(/\n/g, "=\n");
str = str.replace(/(.)=\n/g, "$1\n");
console.log(str);
Explanation -
After the first replacement/s, the output looks like:
=
=
abc def.=
=
*=
=
Then, you replace any characters followed by a =\n and replace it with that same character (given by $1), followed by a newline.
Your desired outcome is "maintain same number of rows but insert = into blank rows".
An empty ("blank") row is a row that matches the regex: ^$.
^ means the beginning of the input string, $ means the end of the input string but if the m modifier is specified (it means "multi-line"), ^ matches the beginning of a line and $ matches the end of a line.
Your code should be as simple as:
input = "\n\nabc def.\n\n*\n\n";
output = str.replace(/^$/mg, '=');
The m modifier changes the meaning of ^ and $ as explained above. The newline characters are not matched by the regex above and consequently they do not need to be present in the replacement string.
The g modifier tells String.replace() to find and replace all the matching substrings, not only the first one (the default behaviour of String.replace()).
Read more about regular expressions in JavaScript.
This should work with two replace :
value.replace(/^\n/, '=\n').replace(/\n\n/g, '\n=\n')
The first replace takes care of the first line if it starts with a blank row.
The second replace takes care of other lines : adding = in blank rows is the same than inserting = between two consecutives \n

Javascript: Remove trailing chars from string if they are non-numeric

I am passing codes to an API. These codes are alphanumeric, like this one: M84.534D
I just found out that the API does not use the trailing letters. In other words, the API is expecting M84.534, no letter D at the end.
The problem I am having is that the format is not the same for the codes.
I may have M84.534DAC, or M84.534.
What I need to accomplish before sending the code is to remove any non-numeric characters from the end of the code, so in the examples:
M84.534D -> I need to pass M84.534
M84.534DAC -> I also need to pass M84.534
Is there any function or regex that will do that?
Thank you in advance to all.
You can use the regex below. It will remove anything from the end of the string that is not a number
let code = 'M84.534DAC'
console.log(code.replace(/[^0-9]+?$/, ""));
[^0-9] matches anything that is not a numer
+? Will match between 1 and unlimited times
$ Will match the end of the string
So linked together, it will match any non numbers at the end of the string, and replace them with nothing.
You could use the following expression:
\D*$
As in:
var somestring = "M84.534D".replace(/\D*$/, '');
console.log(somestring);
Explanation:
\D stands for not \d, the star * means zero or more times (greedily) and the $ anchors the expression to the end of the string.
Given your limited data sample, this simple regular expression does the trick. You just replace the match with an empty string.
I've used document.write just so we can see the results. You use this whatever way you want.
var testData = [
'M84.534D',
'M84.534DAC'
]
regex = /\D+$/
testData.forEach((item) => {
var cleanValue = item.replace(regex, '')
document.write(cleanValue + '<br>')
})
RegEx breakdown:
\D = Anything that's not a digit
+ = One or more occurrences
$ = End of line/input

javascript find 3rd occureance of a substring in a string

I am trying to extract the substring between 3rd occurance of '|' character and ';GTSet' string within string
For Example, if my string is "AP0|#c7477474-376c-abab-2990-918aac222213;L0|#0a4a23b12-125a-2ac2-3939-333aav111111|ABC xxx;pATeND|#222222ANCJ-VCVC-2262-737373-3838383";
I would like to extract "ABC xxx" from above string using javascript.
I have tried following options
var str = "AP0|#c7477474-376c-abab-2990-918aac222213;L0|#0a4a23b12-125a-2ac2-3939-333aav111111|ABC xxx;pATeND|#222222ANCJ-VCVC-2262-737373-3838383";
alert(str.match(/^|\;pATeND(.*)$/gm));
//var n = str.search(";pATeND");
//to get the 3rd occurance of | character
//var m = str.search("s/\(.\{-}\z|\)\{3}");
This lookahead regex should work:
/[^|;]+(?=;pATeND)/
RegEx Demo
Or if paTeND text is know known then grab the value after 3rd |:
^(?:[^|]*\|){3}([^|;]+)
and use captured group #1.
Demo 2

Replace multiple spaces, multiple occurrences of a comma

I am trying to clean an input field client side.
Current Value
string = 'word, another word,word,,,,,, another word, ,,;
Desired Value after cleaning
string = 'word,another word,word,another word;
Simplified version of what I have tried http://jsfiddle.net/zg2e7/362/
You can use
var str = 'word,word,word,,,,,new word, , another word';
document.body.innerHTML = str.replace(/(?:\s*,+)+\s*/g, ',');
You need to use g modifier to find and replace all instances
You need to also match optional whitespace between commas and on both sides of them.
Regex explanation:
(?:\s*,+)+ - 1 or more sequences of
\s* - 0 or more whitespace characters
,+ - 1 or more commas.
string = 'word, another word,word,,,,,, another word, ,,';
console.log(string.replace(/(,)[,\s]+|(\s)\s+/g ,'$1').replace(/^,|,$/g,''));
Try using split and trim and map and join rather than regex being that regex can be a bit clunky.
$.map(str.split(','),function(item,i){
if(item.trim()){
return item.trim()
}
}).join(',')
So split the string by the , and then use the map function to combine them. If the item has value after being trimmed then keep the value. Then after it has been mapped to a array of the valid values join them with a comma.

Categories

Resources