1

I have table structure where I need to capture the Auth code. I have used the regex and matcher method find(). However, there will be multiple codes generated and I need to get the recent one. I tried below code which captures only 1st occurrence. Please let me know How I can capture last occurrence of the code.

Code:

String mobilenumber="00955555555555"; 

//Date validate = null;

    {
    List<WebElement> rows = driver1.findElements(By.cssSelector("tr"));
    for (WebElement row : rows)
    {
        String text = row.getText();
        if (text.contains(mobilenumber))
        {
            String regex = ": (\\d+)"; //Your authentication code is
            Pattern pattern = Pattern.compile(regex);
            Matcher matcher = pattern.matcher(text);

            if (matcher.find())             
                 {

                valueis = matcher.group(1);
                System.out.println(valueis);
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Aditya
  • 457
  • 2
  • 8
  • 27
  • Possible duplicate of [Find the last match with Java regex matcher](http://stackoverflow.com/questions/6417435/find-the-last-match-with-java-regex-matcher) – Ole V.V. Apr 01 '17 at 12:12

2 Answers2

2

There are (maybe not surprising) more ways to obtain this. Here are a couple.

One, keep matching until there are no more matches. The last match is — the last match.

        String valueis = null;
        while (matcher.find()) {
            valueis = matcher.group(1);
        }
        System.out.println(valueis);

Two, alternatively in your regular expression first match as much of the string as you can before the colon and number:

        String regex = ".*: (\\d+)"; // Your authentication code is

Since the * quantifier is greedy, this will match the last number first. For a simple test of the latter, try:

    String regex = ".*: (\\d+)";
    Pattern pattern = Pattern.compile(regex);

    String text = "00955555555555 auth: 44; auth: 77 end";
    Matcher matcher = pattern.matcher(text);
    if (matcher.find()) {
        String valueis = matcher.group(1);
        System.out.println(valueis);
    }       

This prints 77.

From the discussion I gather that there is only one authentication code (one regex match) in each table row (<tr> element), but the same mobile number may occur in more than one table row, and if so, you want the last (most recent) occurrence. This seems not to be a regular expression problem, but a problem of program logic. Here’s my attempt to solve it:

    String regex = ": (\\d+)"; // Your authentication code is
    Pattern pattern = Pattern.compile(regex);

    String valueis = null;
    for (WebElement row : rows) {
        String text = row.getText();
        if (text.contains(mobilenumber)) {
            Matcher matcher = pattern.matcher(text);

            if (matcher.find()) {
                valueis = matcher.group(1);
            }
        }
    }
    if (valueis == null) {
        System.out.println("Not found");
    } else {
        System.out.println("Last occurrence was " + valueis);
    }
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
  • I tried adding the * quantifier but I'm not seeing what I want to Still Auth code which is generated previously was selected but not the one which is newly generated – Aditya Apr 01 '17 at 12:32
  • Previously, does that mean it occurs in a previous `WebElement` or just earlier in the text of the same `WebElement`? – Ole V.V. Apr 01 '17 at 12:43
  • it appears in a tag in a table and everytime a auth code is generated it displays dynamically in any tag – Aditya Apr 01 '17 at 12:47
  • `    00955111111111    2017-04-01 13:32:41.88    Your authentication code is: 59714 to transfer AED 14.00 through online/mobile banking. If you have not requested any transfer, please contact the bank IMMEDIATELY on 00971 600 54 0000. ` – Aditya Apr 01 '17 at 12:48
  • everytime I run the script, the old code is getting picked but not the new one. that is my issue – Aditya Apr 01 '17 at 12:59
  • I see only one occurrence of your pattern in the ``. Are you saying the same mobile number may occur in more than one table row, and if so, you want the last (most recent)? You need to explain more precisely. – Ole V.V. Apr 01 '17 at 13:01
  • 1
    yes the mobile number occurs more than in one table row and I need to capture the most recent one. Sorry If I'm Unclear – Aditya Apr 01 '17 at 13:12
  • 1
    Thnx for letting me know about it. – Aditya Apr 01 '17 at 13:37
  • Your edit also is not working. The same code is what I have with me but still the latest one is not getting picked. – Aditya Apr 01 '17 at 13:57
  • Interesting. From here I cannot tell why not. Which one is it picking, if any at all? Are you sure there is an authentication code in the expected format in the last row with the mobile number? Could there be more than one regex match in that row? PS Feel free to unaccept the answer until you have something that works. – Ole V.V. Apr 01 '17 at 14:15
  • As i said it is picking only the old one but not the recent one. yes auth code is displayed in expected format . No there is only one regex expression in that row – Aditya Apr 02 '17 at 05:54
  • So I take it that there is a regex match in either row, but the program doesn’t find the one in the most recent row. That sounds weird indeed. I haven’t got an idea immediately. Wonder if you can boil the problem down to [a Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve)? – Ole V.V. Apr 02 '17 at 05:58
  • You can try going through the program in your debugger. Verify that when handling the most recent row, `text` does contain both the mobile number and the authentication code, and see which path through the two `if` statements the program takes. – Ole V.V. Apr 02 '17 at 06:01
  • Ok, let me give a try and get back if in case if doesn't work out – Aditya Apr 02 '17 at 06:08
  • I tried all options but still the recent one is not getting picked. – Aditya Apr 02 '17 at 11:51
  • I have added break statement after I found the first pattern and it is working fine . – Aditya Apr 02 '17 at 13:35
0

If you want to last set of digits in input then use this regex with a negative lookahead:

\d+(?!.*\d)

In Java:

String regex = "\\d+(?!.*\\d)";

RegEx Demo

RegEx Breakup:

  • \d+ - Match 1 or more digits
  • (?!.*\d) - Negative lookahead that asserts we don't have any more digits ahead
anubhava
  • 761,203
  • 64
  • 569
  • 643