0

Given the following input:

Invoice Date: {InvoiceDate(dd.mm.YYYY)}
Inoice Number: {InvoiceNumber}

I am trying to extract

  • Match 1:
    1. InvoiceDate
    2. dd.mm.YYYY
  • Match 2:
    1. InvoiceNumber

I got this regex working for the invoice Date:

\{([^}]+)\(([^)]+)\)\}

First regex result

But obiously, (dd.mm.YYYY) is not optional.

Then I tried this regex:

\{([^}]+)(?:\(([^)]+)\))?\}

Using (?:)? syntax seems to ignore my inner captching group (dd.mm.YYYY)

Second Regex result

So how can I make \(([^)]+)\) optional?

Christian Gollhardt
  • 16,510
  • 17
  • 74
  • 111

3 Answers3

2

You need to make the first capture group lazy:

\{([^}]+?)(?:\(([^)]+)\))?\}
        ^

See the demo here.

Or, restrict the characters in the first capture group with ^( so it only matches up to the parenthesis:

\{([^(]+)(?:\(([^)]+)\))?\}
     ^
Psidom
  • 209,562
  • 33
  • 339
  • 356
1

I got it to work typing from scratch, then I had to compare side by side to see what the difference was in our answers:

/\{([^}(]+)(?:\(([^)]+)\))?\}/ // my answer
/\{([^}]+)(?:\(([^)]+)\))?\}/  // your answer

You can see that I specified your first capture group to not include open round bracket. Yours would have been capturing the whole string Invoicedate(dd.mm.YYYY) in the first group, leaving nothing for the second.

Here's the link.

arbuthnott
  • 3,819
  • 2
  • 8
  • 21
0

Why not grab each thing separately?

invoice date: {(.*?)\((.*?)\)}.*?invoice number: {(.*?)}

  • Flags: g, i, s
  • Steps: 348

Demo

linden2015
  • 887
  • 7
  • 9