Example

Invoice Parsing

Invoice fields from documents.

Parse a multi-line invoice using reusable money, date, and payment-term specifications.

What it shows

  • Imports reusable money, date, and payment-term specifications.
  • InvoiceNumber combines a letter prefix with an integer sequence.
  • InvoiceHeader and InvoiceSection separate document structure from individual values.
  • Invoice contains one header and repeated sections.

Try changing Net 30 to Due on Receipt, or Total Amount to Total.

Specs

types/number.yml
Number:
  Decimal: '\d+(,\d{3})*\.\d+'
  Integer: '\d+(,\d{3})*'
types/currency.yml
Currency:
  USD: [ 'USD', 'US\$', '\$' ]
  EUR: [ 'EUR', '€' ]
  GBP: [ 'GBP', '£' ]
types/money.yml
$imports: [ 'number', 'currency' ]

$flags: 'OPTIONAL_WHITESPACE'

Money:
  $fields:
    currency: Currency
    amount: Number
  $patterns:
    - '#{currency} #{amount}'
    - '#{amount} #{currency}'
types/date.yml
$imports: 'number'

Date:
  YearMonthDay:
    $fields:
      year: { $type: Number::Integer, $match: '\d{4}' }
      month: { $type: Number::Integer, $match: '0[1-9]|1[0-2]' }
      day: { $type: Number::Integer, $match: '0[1-9]|[12]\d|3[01]' }
    $patterns: '#{year}-#{month}-#{day}'
types/payment-terms.yml
$imports: 'number'

PaymentTerms:

  NetDays:
    $fields:
      days: Number::Integer
    $patterns: 'Net #{days}'

  DueOnReceipt: 'Due on Receipt'
spec.yml
$imports: [ 'types/money', 'types/date', 'types/payment-terms' ]

$flags: [ 'CASE_INSENSITIVE', 'MULTILINE', 'FLEXIBLE_WHITESPACE' ]

InvoiceNumber: '[A-Z]{2,5}-${Number::Integer}'

InvoiceHeader:
  $fields:
    invoiceNumber: InvoiceNumber
  $patterns: 'Invoice (No\.?|#):\s*#{invoiceNumber}'
InvoiceSection:

  DateLine:
    $fields:
      invoiceDate: Date
    $patterns: 'Invoice Date:\s*#{invoiceDate}'

  BillingRecipientLine:
    $types:
      ClientName: '.*?'
    $fields:
      billingRecipient: ClientName
    $patterns: 'Bill To:\s*#{billingRecipient}$'

  SubtotalLine:
    $fields:
      subtotal: Money
    $patterns: 'Subtotal:\s*#{subtotal}'

  TaxLine:
    $fields:
      tax: Money
    $patterns: 'Tax:\s*#{tax}'

  TotalLine:
    $fields:
      total: Money
    $patterns: 'Total( Amount)?:\s*#{total}'

  PaymentTermsLine:
    $fields:
      paymentTerms: PaymentTerms
    $patterns: 'Payment Terms:\s*#{paymentTerms}'

Invoice: '${InvoiceHeader}( ${InvoiceSection})+'

Try it liveOpen Invoice Parsing in StudioTweak the spec, paste your own input, and see the parse tree update in real time.

Or browse other examples →