Example

Textual Numbers

English number words.

← All examples

Specification

$flags: 'WORD_BOUNDARY'

Number:
  BelowMillion:
    BelowThousand:
      BelowHundred:
        Unit:
          Zero: 'zero'
          One: 'one'
          Two: 'two'
          Three: 'three'
          Four: 'four'
          Five: 'five'
          Six: 'six'
          Seven: 'seven'
          Eight: 'eight'
          Nine: 'nine'
        TwoDigit:
          Teen:
            Ten: 'ten'
            Eleven: 'eleven'
            Twelve: 'twelve'
            Thirteen: 'thirteen'
            Fourteen: 'fourteen'
            Fifteen: 'fifteen'
            Sixteen: 'sixteen'
            Seventeen: 'seventeen'
            Eighteen: 'eighteen'
            Nineteen: 'nineteen'
          Tens:
            Twenty: 'twenty'
            Thirty: 'thirty'
            Forty: 'forty'
            Fifty: 'fifty'
            Sixty: 'sixty'
            Seventy: 'seventy'
            Eighty: 'eighty'
            Ninety: 'ninety'
          Compound:
            $fields: { tens: Tens, unit: Unit }
            $patterns: '#{tens}(-| )#{unit}'
      Hundred:
        $fields: { hundreds: Unit, remainder: BelowHundred }
        $patterns: '#{hundreds} hundred( and #{remainder})?'
    Thousand:
      $fields: { thousands: BelowThousand, remainder: BelowThousand }
      $patterns: '#{thousands} thousand( #{remainder})?'
  Million:
    $fields: { millions: BelowThousand, remainder: BelowMillion }
    $patterns: '#{millions} million( #{remainder})?'

Sample input

seven cats and thirteen dogs
twenty-seven runners
four hundred and ninety-six chairs
one hundred and two
ninety-four thousand six hundred and seventy-two bricks
one hundred and sixteen million three hundred and twenty-eight thousand dollars

Result

[
  {
    "type": "Number::BelowMillion::BelowThousand::BelowHundred::Unit::Seven",
    "text": "seven",
    "start": 0,
    "end": 5
  },
  {
    "type": "Number::BelowMillion::BelowThousand::BelowHundred::TwoDigit::Teen::Thirteen",
    "text": "thirteen",
    "start": 15,
    "end": 23
  },
  {
    "type": "Number::BelowMillion::BelowThousand::BelowHundred::TwoDigit::Compound",
    "text": "twenty-seven",
    "start": 29,
    "end": 41,
    "fields": [
      {
        "type": "Number::BelowMillion::BelowThousand::BelowHundred::TwoDigit::Tens::Twenty",
        "field": "tens",
        "text": "twenty",
        "start": 29,
        "end": 35
      },
      {
        "type": "Number::BelowMillion::BelowThousand::BelowHundred::Unit::Seven",
        "field": "unit",
        "text": "seven",
        "start": 36,
        "end": 41
      }
    ]
  },
  {
    "type": "Number::BelowMillion::BelowThousand::Hundred",
    "text": "four hundred and ninety-six",
    "start": 50,
    "end": 77,
    "fields": [
      {
        "type": "Number::BelowMillion::BelowThousand::BelowHundred::Unit::Four",
        "field": "hundreds",
        "text": "four",
        "start": 50,
        "end": 54
      },
      {
        "type": "Number::BelowMillion::BelowThousand::BelowHundred::TwoDigit::Compound",
        "field": "remainder",
        "text": "ninety-six",
        "start": 67,
        "end": 77,
        "fields": [
          {
            "type": "Number::BelowMillion::BelowThousand::BelowHundred::TwoDigit::Tens::Ninety",
            "field": "tens",
            "text": "ninety",
            "start": 67,
            "end": 73
          },
          {
            "type": "Number::BelowMillion::BelowThousand::BelowHundred::Unit::Six",
            "field": "unit",
            "text": "six",
            "start": 74,
            "end": 77
          }
        ]
      }
    ]
  },
  {
    "type": "Number::BelowMillion::BelowThousand::Hundred",
    "text": "one hundred and two",
    "start": 85,
    "end": 104,
    "fields": [
      {
        "type": "Number::BelowMillion::BelowThousand::BelowHundred::Unit::One",
        "field": "hundreds",
        "text": "one",
        "start": 85,
        "end": 88
      },
      {
        "type": "Number::BelowMillion::BelowThousand::BelowHundred::Unit::Two",
        "field": "remainder",
        "text": "two",
        "start": 101,
        "end": 104
      }
    ]
  },
  {
    "type": "Number::BelowMillion::Thousand",
    "text": "ninety-four thousand six hundred and seventy-two",
    "start": 105,
    "end": 153,
    "fields": [
      {
        "type": "Number::BelowMillion::BelowThousand::BelowHundred::TwoDigit::Compound",
        "field": "thousands",
        "text": "ninety-four",
        "start": 105,
        "end": 116,
        "fields": [
          {
            "type": "Number::BelowMillion::BelowThousand::BelowHundred::TwoDigit::Tens::Ninety",
            "field": "tens",
            "text": "ninety",
            "start": 105,
            "end": 111
          },
          {
            "type": "Number::BelowMillion::BelowThousand::BelowHundred::Unit::Four",
            "field": "unit",
            "text": "four",
            "start": 112,
            "end": 116
          }
        ]
      },
      {
        "type": "Number::BelowMillion::BelowThousand::Hundred",
        "field": "remainder",
        "text": "six hundred and seventy-two",
        "start": 126,
        "end": 153,
        "fields": [
          {
            "type": "Number::BelowMillion::BelowThousand::BelowHundred::Unit::Six",
            "field": "hundreds",
            "text": "six",
            "start": 126,
            "end": 129
          },
          {
            "type": "Number::BelowMillion::BelowThousand::BelowHundred::TwoDigit::Compound",
            "field": "remainder",
            "text": "seventy-two",
            "start": 142,
            "end": 153,
            "fields": [
              {
                "type": "Number::BelowMillion::BelowThousand::BelowHundred::TwoDigit::Tens::Seventy",
                "field": "tens",
                "text": "seventy",
                "start": 142,
                "end": 149
              },
              {
                "type": "Number::BelowMillion::BelowThousand::BelowHundred::Unit::Two",
                "field": "unit",
                "text": "two",
                "start": 150,
                "end": 153
              }
            ]
          }
        ]
      }
    ]
  },
  {
    "type": "Number::Million",
    "text": "one hundred and sixteen million three hundred and twenty-eight thousand",
    "start": 161,
    "end": 232,
    "fields": [
      {
        "type": "Number::BelowMillion::BelowThousand::Hundred",
        "field": "millions",
        "text": "one hundred and sixteen",
        "start": 161,
        "end": 184,
        "fields": [
          {
            "type": "Number::BelowMillion::BelowThousand::BelowHundred::Unit::One",
            "field": "hundreds",
            "text": "one",
            "start": 161,
            "end": 164
          },
          {
            "type": "Number::BelowMillion::BelowThousand::BelowHundred::TwoDigit::Teen::Sixteen",
            "field": "remainder",
            "text": "sixteen",
            "start": 177,
            "end": 184
          }
        ]
      },
      {
        "type": "Number::BelowMillion::Thousand",
        "field": "remainder",
        "text": "three hundred and twenty-eight thousand",
        "start": 193,
        "end": 232,
        "fields": [
          {
            "type": "Number::BelowMillion::BelowThousand::Hundred",
            "field": "thousands",
            "text": "three hundred and twenty-eight",
            "start": 193,
            "end": 223,
            "fields": [
              {
                "type": "Number::BelowMillion::BelowThousand::BelowHundred::Unit::Three",
                "field": "hundreds",
                "text": "three",
                "start": 193,
                "end": 198
              },
              {
                "type": "Number::BelowMillion::BelowThousand::BelowHundred::TwoDigit::Compound",
                "field": "remainder",
                "text": "twenty-eight",
                "start": 211,
                "end": 223,
                "fields": [
                  {
                    "type": "Number::BelowMillion::BelowThousand::BelowHundred::TwoDigit::Tens::Twenty",
                    "field": "tens",
                    "text": "twenty",
                    "start": 211,
                    "end": 217
                  },
                  {
                    "type": "Number::BelowMillion::BelowThousand::BelowHundred::Unit::Eight",
                    "field": "unit",
                    "text": "eight",
                    "start": 218,
                    "end": 223
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  }
]

Notes

# Textual Numbers

Recognize English number words as a semantic hierarchy.

## Notice

- Units, teens, and tens are primitive semantic types.
- Larger phrases compose smaller ones.
- Fields show how hundreds, thousands, millions, and remainders are assembled.
- The result keeps structure that a flat regex would hide.

Try changing `twenty-seven` to `twenty seven`.