Question: I've been working on a basic ATM-like application for my Intro to Programming course at my High School. I am trying to match a list of pre-existing "PIN codes" so that a user adding themselves to the database cannot use the same PIN as an existing user, but the following code is always resulting in a 'false' output.

```
        newName01 = txtFirstName.Text;
        newName02 = txtLastName.Text;
        newPin = Convert.ToInt32(txtCreatePin.Text);
        confirmPin = Convert.ToInt32(txtConfirmPin.Text);
        float E = float.Parse(txtDepositInt.Text, CultureInfo.InvariantCulture.NumberFormat);

        for (var i = 0; i < lstinfo.Count; i++)
        {
            if(newPin == lstinfo[i].pin)
            {
                active = false;
            }
            else
            {
                active = true;
            }
        }

        if(active == true)
        {
            lstinfo.Add(new AccountInfo(newName01, newName02, newPin, E));
            Submit_info();
        }

```

Answer: 
You only get the first capturing group because you match `.*?` which is non greedy and then capture in a group matching zero or more times a word character or a dot `[\w\.]*` followed by either Exception or Error. The first time that will match is `RecoverableBuildException` and is captured group 1.

What follows is `(: .*?\n)?` but after matching the first group there is no `:` to match so the second group does not match.

You might use::

`Traceback \(most recent call last\):(?:\n.*)+?\n(.*?(?:Exception|Error):)\s*(.+)`

[Regex demo](https://regex101.com/r/5rWj4P/1)

That will match:

* `Traceback \(most recent call last\):` Match literally
* `(?:\n.*)+?` Repeat in a non capturing group matching a newline followed by 0+ times any character
* `\n(.*?(?:Exception|Error):) Match newline and capturinggroup 0+ characters non greedy and than match Exception of Error followed by`:`
* `\s*` Match 0+ whitespace characters
* `(.+)` Capturing group 1+ times any character

For example:

```
EXCEPTION_PATTERN = re.compile(
    r"Traceback \(most recent call last\):(?:\n.*)+?\n(.*?(?:Exception|Error):)\s*(.+)"
)
ex_match = EXCEPTION_PATTERN.findall(st)
print(ex_match)  # [('common.exceptions.BuildException:', 'test error')]

```
The ".*?" in the middle of your regex is non-greedy: it will match as little as possible to satisfy the expression. Because the "(: .*?\n)?" is optional (that's what the final '?' does: match 0 or 1 of the stuff in the parens) the "Exception" at the end of "RecoverableBuildException" satisfies the expression.

There are two ways to get the results you want:

* Remove the '?' from the ".\*?" in the middle to make it greedy, so that it matches as much as possible.
* Move the ':' before the final parenthetical so the expression ends with "|Error)):( .\*?\n)?" (or even just removing all but the ':', so it ends with "|Error)):").