Scans a string into the numbers it holds and the text around
them, from the tokens of Localize.Number.Lexer.
The scanner walks the tokens once. At each token it takes the
longest run that has the shape of a number below, and hands the run
to Localize.Number.Grammar: the run is a number where the grammar
reads one, and a piece of text of its own where it does not, since
the grammar's rules are stricter than the shape. Everything else is
text, returned as it was written, with consecutive pieces of text
joined into one.
Grammar
scan = { number | text } ;
number = bidi, [ sign, bidi ], integer, [ fraction ], [ exponent ] ;
bidi = { bidi-control } ;
integer = digits, { digits | "_" | group, digits } ;
fraction = decimal, zero-dash | decimal, { digits | "_" }- ;
zero-dash = dash, [ dash ] ;
exponent = ( "e" | "E" ), [ sign ], digits ;decimal and group are the marks of the lexicon's first reading,
the separators of the locale, the number system and the options in
hand, and a space is a group where that reading groups with one.
The shape is narrower than the grammar's: a sign comes only before
the digits and touches them, there are no parentheses and no space
inside the number, so "- 5" is text and a number and "(5)" three
pieces. The rules that complete the shape are the named functions
below:
a group separator is followed by a plausible group: two digits or more leniently, exactly the locale's group strictly (
plausible_group?/3);a decimal separator is followed by a digit, an underscore, or the dashes of a zero fraction, which are read leniently only (
fraction/2,zero_dash/2);a zero fraction is one or two dashes with no digit after them, and ends the number (
zero_dash/2);an exponent is an ASCII
eorE, a sign and digits, after the integer or after a fraction written with digits (exponent/1);a bidi control before the digits, or between the sign and the digits, is part of the number; one after the digits is text (
number_run/2).
Summary
Functions
Scans a string into numbers and text with a lexicon.
Functions
@spec scan(String.t(), Localize.Number.Lexicon.t(), Keyword.t()) :: [ String.t() | integer() | float() | Decimal.t() ]
Scans a string into numbers and text with a lexicon.
Arguments
stringis the text to scan.lexiconis theLocalize.Number.Lexicon.t/0to scan it with.optionsis a keyword list of options.
Options
:numberis the type to read each number as::integer,:float,:decimal, ornilto read an integer where the text is one and a float otherwise.:groupingis how the grammar checks group separators::lenient,:strictor:sizes.:lenientisfalseto take only groups of the locale's sizes and no zero fraction. The default istrue.:max_number_bytesis the longest run, in bytes, that is read as a number; a longer one is text. The default is no limit.:max_decimal_exponentbounds the exponent of a decimal read.
Returns
- A list of strings and numbers.
Examples
iex> {:ok, fr} = Localize.validate_locale(:fr)
iex> {:ok, lexicon} = Localize.Number.Lexicon.fetch(fr, :latn, [])
iex> Localize.Number.Scanner.scan("2 000 et 3 000", lexicon, [])
[2000, " et ", 3000]
iex> {:ok, en} = Localize.validate_locale(:en)
iex> {:ok, lexicon} = Localize.Number.Lexicon.fetch(en, :latn, [])
iex> Localize.Number.Scanner.scan("v1.2.3 and 4,5", lexicon, [])
["v", 1.2, ".", 3, " and ", 4, ",", 5]