regex?

Post your questions and help other users.

Moderator: Martin

pmgnt
Posts: 26
Joined: 15 Jul 2016 00:34

regex?

Post by pmgnt » 23 Jul 2020 00:48

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!

User avatar
Desmanto
Posts: 2709
Joined: 21 Jul 2017 17:50

Re: regex?

Post by Desmanto » 23 Jul 2020 08:08

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.
Index of Automagic useful thread List of my other useful posts (and others')
Xiaomi Redmi Note 5 (whyred), AOSP Extended v6.7 build 20200310 Official, Android Pie 9.0, Rooted.

User avatar
Hit
Posts: 91
Joined: 20 Jan 2020 11:31

Re: regex?

Post by Hit » 23 Jul 2020 16:23

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"

pmgnt
Posts: 26
Joined: 15 Jul 2016 00:34

Re: regex?

Post by pmgnt » 24 Jul 2020 02:40

Perfect!

Many thanks to Desmanto for such a detailed explanation!
Also big thanks to Hit for this incredebly short code!

Best regards.

User avatar
Hit
Posts: 91
Joined: 20 Jan 2020 11:31

Re: regex?

Post by Hit » 24 Jul 2020 02:55

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"

User avatar
Hit
Posts: 91
Joined: 20 Jan 2020 11:31

Re: regex?

Post by Hit » 24 Jul 2020 06:48

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.

pmgnt
Posts: 26
Joined: 15 Jul 2016 00:34

Re: regex?

Post by pmgnt » 25 Jul 2020 14:55

@Hit

Another issue with your code..

string = "aaaa09aaaa"

makes

string = "aaaa010aaaa"

instead of "aaaa10aaaa"

User avatar
Hit
Posts: 91
Joined: 20 Jan 2020 11:31

Re: regex?

Post by Hit » 25 Jul 2020 15:15

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.

User avatar
Desmanto
Posts: 2709
Joined: 21 Jul 2017 17:50

Re: regex?

Post by Desmanto » 26 Jul 2020 17:45

@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.
Last edited by Desmanto on 28 Jul 2020 10:17, edited 1 time in total.
Index of Automagic useful thread List of my other useful posts (and others')
Xiaomi Redmi Note 5 (whyred), AOSP Extended v6.7 build 20200310 Official, Android Pie 9.0, Rooted.

pmgnt
Posts: 26
Joined: 15 Jul 2016 00:34

Re: regex?

Post by pmgnt » 27 Jul 2020 17:44

@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!

Post Reply