Page 1 of 2
regex?
Posted: 23 Jul 2020 00:48
by pmgnt
Hii guys,
I need to find the number in a string variable and add 1
Like ;
xxxxx_1 becomes xxxxx_2
or
xxxx1xxxx becomes xxxx2xxxx
...
My code below works fine unless the number has leading zero's. Like;
xxxx_01 or xxxx001xxxx
Could anyone give me an idea?
My code so far;
value = "xxxx_1";
//value = "xxxx1xxxx"
groups = newList(); matches(value, "\\D*(\\d*).*", groups);
new_value = replace(groups[0], groups[1], groups[1]+1);
log(new_value)
Thank you!
Re: regex?
Posted: 23 Jul 2020 08:08
by Desmanto
Can't replace directly, as you still need extra check on the number which end at 9. The easiest way is to pad the number to bigger padding and take the right char as many as the length.
Code: Select all
name = "Name1\nName9\nMid04end\nMid99end\nSpace 009 a\nSpace 999 b";
find = findAll(name, ".*?(\\d+).*", true);
rename = newList();
for(i in find)
{
num = i[1] + 1; //increment num by 1
r = if(length(i[1]) > length(num)) length(i[1]) else length(num);
//check length after added
newnum = right("{num,numberformat,0000000000}", r); //reserve 10 digit and take right digit as many as r
addElement(rename, replace(i[0], i[1], newnum));
}
show = join(rename, "\n");
- First we capture the group.
- Then we increment the captured number by 1.
- Check if its' original length is longer than the captured after incremented.
- If yes, means it has padding, use the original padded length. If no, no padding, use the usual length.
- use right() to take the length, I use 10 zero padding, but you can use shorter or longer.
- replace the number, and add to new List.
Try it out in debug dialog and check if it fit to your need.
Re: regex?
Posted: 23 Jul 2020 16:23
by Hit
Easy solution:
Before:
string = "aaaaaa000010203bbbbbb";
l = findAll(string, "[1-9]\\d*");
if (length(l)>0) string = replace(string, l[0], l[0]+1);
Now:
string = "aaaaaa000010204bbbbbb"
Re: regex?
Posted: 24 Jul 2020 02:40
by pmgnt
Perfect!
Many thanks to Desmanto for such a detailed explanation!
Also big thanks to Hit for this incredebly short code!
Best regards.
Re: regex?
Posted: 24 Jul 2020 02:55
by Hit
Hello @pmgnt.
I should tell you that my code above assumes that the the number will never contain only zero. Thus
string = "aaaaaa00000bbbbbb";
will be still:
string = "aaaaaa00000bbbbbb"
Re: regex?
Posted: 24 Jul 2020 06:48
by Hit
You guys should use Desmanto's code.
Seem a bit complicate but it works for most case.
For special case that you don't want to match only zeros, you can try my code.
Re: regex?
Posted: 25 Jul 2020 14:55
by pmgnt
@Hit
Another issue with your code..
string = "aaaa09aaaa"
makes
string = "aaaa010aaaa"
instead of "aaaa10aaaa"
Re: regex?
Posted: 25 Jul 2020 15:15
by Hit
I know that. I have made another one that work with most case but since we have Desmanto's code, I don't upload here.
And I misunderstood your need that we should preserve zeros. Sorry.
Re: regex?
Posted: 26 Jul 2020 17:45
by Desmanto
@pmgnt : I have been thinking to shorten the code, I find that we can use max for the length checking. Then I keep thinking on what if the name contains multiple number, such as
AM tutor S1 EP1. I assume you most likely want to increment only the EP1 > EP2, not the S1. Hence I use another regex pattern to replace, after we have catch the last number. Can't use simple replace, as it will replace both S1 and EP1 at the same time.
I found that you want to use that on 1 name only at one time. My script above is for multiple lines. If you only need one line, then below is the improvement. You can still loop the code and feed it with list and save it to other list.
Code: Select all
name = "AM S1 Ep1";
f = findAll(name, ".*?(\\d+)\\D*$", true);
if(!isEmpty(f))
{
num = f[0][1] + 1; //increment num by 1
r = max(length(f[0][1]), length(num)); //check if after added
newnum = right("{num,numberformat,0000000000}", r); //reserve 10 digit and take right digit as many as r
newname = replaceAll(name, "(.*?)(\\d+)(\\D*)$", "$1" + newnum + "$3"); //same regex pattern, but with new capture group and replacement
}
If you already familiar with the code, you can still shorten the code by omitting the num and r, and put it into the newnum directly.
Code: Select all
if(!isEmpty(f))
{
newnum = right("{f[0][1]+1,numberformat,0000000000}", max(length(f[0][1]), length(f[0][1] + 1)));
newname = replaceAll(name, "(.*?)(\\d+)(\\D*)$", "$1" + newnum + "$3");
}
But this make the code harder to decipher later, hence not preferred.
Re: regex?
Posted: 27 Jul 2020 17:44
by pmgnt
@Desmanto
Wow thanks for ur time again!
Yes you are right i need it for single name at one time.
In this case the names are numbered email addresses.
So i had to change the regex pattern a little.
Works great so far...
But im not the best with regex and its pattern so maybe you can confirm my adjustment...
name = "
xxxx1@gmail.com";
f = findAll(name, ".*?(\\d+)\D*", true); // removed '$' at end of pattern
if(!isEmpty(f))
{
num = f[0][1] + 1;
r = max(length(f[0][1]), length(num));
newnum = right("{num,numberformat,0000000000}", r);
newname = replaceAll(name, "(.*?)(\\d+)(\D*)", "$1" + newnum + "$3");
log(newname)
}
Thank you again!