Unit::Parser
Parser for converting human-readable strings into measurement objects
The Parser module provides a flexible string parsing system that can handle various formats of measurement input, including decimal numbers, fractions, and different unit representations.
Supported Formats
Numeric Values
- Decimal:
"10.5","0.001","-3.14" - Fractions:
"1/2","3/4","10/3" - Negative values:
"-5","-1/2"
Unit Matching
- Full names:
"kilogram","pound","meter" - Plurals:
"kilograms","pounds","meters" - Symbols:
"kg","lb","m" - Case insensitive:
"KG","Kilogram","POUND"
Whitespace Handling
- No space:
"10kg" - Single space:
"10 kg" - Multiple spaces:
"10 kg" - Leading/trailing:
" 10 kg "
Examples
# Basic decimal parsing
weight = Unit::Parser.parse("10.5 kg", Unit::Weight)
length = Unit::Parser.parse("2.5 meters", Unit::Length)
# Fraction parsing
half_pound = Unit::Parser.parse("1/2 pound", Unit::Weight)
quarter_cup = Unit::Parser.parse("1/4 cup", Unit::Volume)
# Various formats
Unit::Parser.parse("10kg", Unit::Weight) # No space
Unit::Parser.parse("10 KG", Unit::Weight) # Uppercase
Unit::Parser.parse("10 kilograms", Unit::Weight) # Plural
# Error handling
Unit::Parser.parse("invalid", Unit::Weight) # Raises ArgumentError
Constants
Regex pattern for matching decimal numbers including negative values
Supports:
- Integers: "10", "-5"
- Decimals: "10.5", "-3.14", "0.001"
- Leading zeros: "0.5", "00.123"
Examples: "10" -> "10" "-5.5" -> "-5.5" "0.001" -> "0.001"
Regex pattern for matching fraction notation (e.g., "1/2", "3/4", "10/3")
Captures:
- Numerator (integer)
- Denominator (integer, must be non-zero)
Examples: "1/2" -> numerator: "1", denominator: "2" "10/3" -> numerator: "10", denominator: "3"
Regex pattern for matching complete measurement strings
Captures:
- Value (decimal or fraction)
- Unit string (letters, letters with slashes, or symbols, case-insensitive)
Supports flexible whitespace between value and unit, including:
- No space between value and unit: "10kg"
- Multiple spaces: "10 kg"
- Tab characters: "10\tkg"
- Leading/trailing whitespace: " 10 kg "
- Density units with slashes: "1.0 g/mL", "62.4 lb/ft³"
Examples: "10 kg" -> value: "10", unit: "kg" "1/2 pound" -> value: "1/2", unit: "pound" "-3.14 meters" -> value: "-3.14", unit: "meters" "5.5kg" -> value: "5.5", unit: "kg" (no space) " 10 kg " -> value: "10", unit: "kg" (extra whitespace) "1.0 g/mL" -> value: "1.0", unit: "g/mL" (density) "62.4 lb/ft³" -> value: "62.4", unit: "lb/ft³" (density)
Class methods
Parses a measurement string into a Weight object.
Accepts various string formats and returns a properly typed Weight measurement. The parser is flexible with whitespace and case-insensitive for units.
# Decimal values
Unit::Parser.parse("10.5 kg", Unit::Weight) # => Weight(10.5, :kilogram)
Unit::Parser.parse("2.25 lb", Unit::Weight) # => Weight(2.25, :pound)
# Fractions
Unit::Parser.parse("1/2 pound", Unit::Weight) # => Weight(0.5, :pound)
Unit::Parser.parse("3/4 oz", Unit::Weight) # => Weight(0.75, :ounce)
# Negative values
Unit::Parser.parse("-3 g", Unit::Weight) # => Weight(-3, :gram)
# Flexible spacing
Unit::Parser.parse("10kg", Unit::Weight) # No space
Unit::Parser.parse("10 kg", Unit::Weight) # Multiple spaces
@param weight_class The Weight class (for type inference) @param input The string to parse @return A new Weight instance @raise ArgumentError if the format is invalid or unit is unknown
Parses a measurement string into a Length object
Examples: parse(Length, "10.5 m") -> Length.new(10.5, Length::Unit::Meter) parse(Length, "1/2 foot") -> Length.new(0.5, Length::Unit::Foot) parse(Length, "-3 cm") -> Length.new(-3, Length::Unit::Centimeter)
Parses a measurement string into a Volume object
Examples: parse(Volume, "2.5 L") -> Volume.new(2.5, Volume::Unit::Liter) parse(Volume, "1/2 cup") -> Volume.new(0.5, Volume::Unit::Cup) parse(Volume, "500 ml") -> Volume.new(500, Volume::Unit::Milliliter)
Parses a measurement string into a Density object
Examples: parse(Density, "1.0 g/mL") -> Density.new(1.0, Density::Unit::GramPerMilliliter) parse(Density, "62.4 lb/ft³") -> Density.new(62.4, Density::Unit::PoundPerCubicFoot) parse(Density, "0.92 g/cc") -> Density.new(0.92, Density::Unit::GramPerCubicCentimeter)
Parses a unit string for Weight measurements
Parses a unit string for Length measurements
Parses a unit string for Volume measurements
Parses a unit string for Density measurements
Parses a value string into either BigDecimal or BigRational
First checks if the value matches the fraction pattern (e.g., "1/2"). If so, creates a BigRational from numerator and denominator. Otherwise, parses as a BigDecimal for decimal values.
Args: value_str: String containing the numeric value to parse
Returns: BigRational for fractions, BigDecimal for decimal values
Raises: ArgumentError: If the value cannot be parsed or denominator is zero
Examples: parse_value("1/2") -> BigRational.new(1, 2) parse_value("10.5") -> BigDecimal.new("10.5") parse_value("-3.14") -> BigDecimal.new("-3.14")