Module:NumberParser: Difference between revisions
From IdleOn MMO Wiki
No edit summary |
No edit summary |
||
Line 67: | Line 67: | ||
-- Check exponential notation (1e20, 2.5e15, ...) | -- Check exponential notation (1e20, 2.5e15, ...) | ||
local base, fraction, exponent = value:match('^(%d*)%.?(%d*)e(%d+)$') | local base, fraction, exponent = value:match('^(%d*)%.?(%d*)e%+*(%d+)$') | ||
if exponent ~= nil then | if exponent ~= nil then | ||
return parse_exponential(base, fraction, exponent) | return parse_exponential(base, fraction, exponent) |
Revision as of 02:59, 11 March 2024
This module parses numbers expressed in different notations and returns a string representation of the number in standard format. This is a helper module that is intended to be used by other modules, rather than called by templates.
Usage
-- First import the module at the start of your module.
local NumberParser = require('Module:NumberParser')
-- Call the parse function with your input.
local input = '5e6'
local output = NumberParser.parse(input)
Supported Notations
Notation | Examples | Notes |
---|---|---|
Standard Notation | 5 , 37 , 1000000000
|
|
Exponential Notation | 3e17 , 2.5e+5 , 7.e15 , .8e+22
|
|
Unit Notation | 14K , 3M , 1.5Q
|
|
Supported Units
- K: 1,000
- M: 1,000,000
- B: 1,000,000,000
- T: 1,000,000,000,000
- Q: 1,000,000,000,000,000
Invalid Numbers
Negative numbers and decimal numbers are not supported.
require('strict')
local p = {}
--- Maps fixed unit suffixes to their exponents. Keys must be lowercase as
--- parsed strings are converted to lowercase to simplify the pattern matching
--- logic.
local UNIT_EXPONENTS = {
k = 3,
m = 6,
b = 9,
t = 12,
q = 15
}
--- Parses a value that is exponential.
--- @param base string? The integer part of the coefficient or nil.
--- @param fraction string? The fraction part of the coefficient, or nil.
--- @param exponent string|number? The exponent.
--- @return string? result The string representation of the parsed integer.
local function parse_exponential(base, fraction, exponent)
-- Both the exponent and coefficient are required.
if exponent == nil or (string.len(base or '') == 0 and string.len(fraction or '') == 0) then
return nil
end
-- Conversion needed because we need to perform some arithmetic with exponent.
exponent = tonumber(exponent)
if exponent == nil then
return nil
end
-- The parsed result cannot have a decimal, so make sure the exponent large
-- enough to account for the fraction part of the coefficient.
local fraction_exponent = fraction ~= nil and fraction:len() or 0
if exponent < fraction_exponent then
return nil
end
local result = base
-- Append the fraction if one was present.
if fraction ~= nil then
result = result .. fraction
exponent = exponent - fraction_exponent
end
-- Append zeroes in place of the exponent.
if exponent > 0 then
result = result .. string.rep('0', exponent)
end
return result
end
--- Parses a string representation of a number in any supported format.
--- @param value string The string representation of the number.
--- @return string? result The string reprentation of the number in standard notation, or nil if the string is invalid.
function p.parse(value)
-- Convert the value to lowercase and trim whitespace to simplify patterns.
value = mw.text.trim(value:lower())
-- The value is already in standard notation.
if value:find('^%d+$') then
return value
end
-- Check exponential notation (1e20, 2.5e15, ...)
local base, fraction, exponent = value:match('^(%d*)%.?(%d*)e%+*(%d+)$')
if exponent ~= nil then
return parse_exponential(base, fraction, exponent)
end
-- Check unit notation (3K, 140M, 75Q, ...)
local base, fraction, unit = value:match('^(%d*)%.?(%d*)(%a)$')
if unit ~= nil then
local exponent = UNIT_EXPONENTS[unit]
if exponent ~= nil then
return parse_exponential(base, fraction, exponent)
end
end
-- Number didn't match any known notations, so return nil so the client can
-- decide how to procede.
return nil
end
return p