decstr

package module
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 23, 2025 License: MIT Imports: 1 Imported by: 0

README

decstr

decstr is a Golang package to handle decimal strings. It provides utilities to normalize, check, detect formats, and convert decimal strings, without relying on external dependencies.

Features

  • Normalize decimal strings:

    • Removes grouping separators.
    • Standardizes the decimal separator to . (dot).
    • Removes leading zeros, trailing zeros, and trailing decimal separators for integers.
  • Detect decimal format (grouping separator, decimal separator, and grouping style).

  • Convert decimal strings to a specified format.

Example

package main

import (
  "fmt"
  "github.com/kpym/decstr"
)

func main() {
    decimal := "1'234'567,89"

    // Normalize example
    normalized := decstr.Normalize(decimal)
    fmt.Println("Normalized:", normalized) // 1234567.89

    // Detect format example
    format, ok := decstr.DetectFormat(decimal)
    fmt.Println("Detected format:", format, "ok:", ok) // Detected format: {`,`, `'`, standard} ok: true
    
	// Convert example
    df := decstr.DecimalFormat{Point: '.', Group: ' ', Standard: false}
    converted, ok := df.Convert(decimal)
    fmt.Println("Converted:", converted, "ok:", ok) // Converted: 12 34 567.89 ok: true
}

Functions

All functions accept both string or []byte as input and return results in the same type. In what follows, only "string" is used for simplicity.

Normalize

Normalizes a decimal string:

  • No grouping separators.
  • Decimal separator is . (dot).
  • No leading or trailing zeros (and no trailing decimal for integers).

If the input string is not a valid decimal, it returns the string as-is.

NormalizeCheck

Same as Normalize, but also returns a boolean indicating whether the string was normalized.

IsNormalized

Checks if the decimal string is normalized.

DetectFormat

Detects the decimal format:

  • Returns the decimal separator.
  • Returns the grouping separator (if any).
  • Indicates whether the grouping is standard (3 digits per group) or non-standard (first 3 digits, then 2 per group).
Convert

Converts a decimal string to the specified format.

Documentation

The package documentation is available at pkg.go.dev.

LICENSE

This package is released under the MIT License.

Decimal Format

Possible decimal writings from Wikipedia:

  • standard grouping (by 3)
    • 1,234,567.89 : Australia, Cambodia, Canada (English-speaking; unofficial), China, Cyprus (currency numbers), Hong Kong, Iran, Ireland, Israel, Japan, Korea, Macau (in Chinese and English text), Malaysia, Mexico, Namibia, New Zealand, Pakistan, Peru (currency numbers), Philippines, Singapore, South Africa (English-speaking; unofficial), Taiwan, Thailand, United Kingdom and other Commonwealth states except Mozambique, United States.
    • 1 234 567.89 : Canada (English-speaking; official), China, Estonia (currency numbers), Hong Kong (in education), Mexico, Namibia, South Africa (English-speaking; unofficial), Sri Lanka, Switzerland (in federal texts for currency numbers only), United Kingdom (in education), United States (in education). SI style (English version) but SI doesn't include currency.
    • 1 234 567,89 : Albania, Belgium (French), Brazil, Bulgaria, Canada (French-speaking), Costa Rica, Croatia, Czech Republic, Estonia, Finland, France, Hungary, Italy (in education), Latin America, Latin Europe, Latvia, Lithuania, Macau (in Portuguese text), Mozambique, Norway, Peru, Poland, Portugal, Russia, Serbia (informal), Slovakia, Slovenia, South Africa (official), Spain (official use since 2010, according to the RAE and CSIC), Sweden, Switzerland (in federal texts, except currency numbers[56]), Ukraine, Vietnam (in education). SI style (French version) but SI doesn't include currency.
    • 1.234.567,89 : Austria, Belgium (Dutch), Bosnia and Herzegovina, Brazil (informal and in technology), Chile, Colombia, Croatia (in bookkeeping and technology), Denmark, Germany, Greece, Indonesia, Italy, Latin America (informal), Netherlands, Romania, Slovenia, Serbia, Spain (used until 2010, inadvisable use according to the RAE and CSIC), Turkey, Uruguay, Vietnam.
    • 1,234,567·89 : Malaysia, Malta, Philippines (uncommon today), Singapore, Taiwan, United Kingdom (older, typically handwritten; in education)
    • 1'234'567.89 : Switzerland (computing), Liechtenstein.
    • 1'234'567,89 : Switzerland (handwriting), Italy (handwriting).
    • 1.234.567'89 : Spain (handwriting, used until 1980s).
  • non standard grouping (3, then by 2)
    • 12,34,567.89 : Bangladesh, India, Nepal, Pakistan
    • 12 34 567.89 : Bangladesh, India, Nepal, Pakistan

Documentation

Overview

decstr is a package for detecting and converting decimal strings. It provides utilities for identifying decimal formats and converting between them.

Example

Example demonstrates general usage of the decstr package, including normalization, format detection, and conversion of decimal strings.

decimal := "1'234'567,89"

// Normalize example
normalized := Normalize(decimal)
fmt.Println("Normalized:", normalized)

// Detect format example
format, ok := DetectFormat(decimal)
fmt.Println("Detected format:", format, "ok:", ok)
// Convert example
df := DecimalFormat{Point: '.', Group: ' ', Standard: false}
converted, ok := df.Convert(decimal)
fmt.Println("Converted:", converted, "ok:", ok)
Output:

Normalized: 1234567.89
Detected format: {`,`, `'`, standard} ok: true
Converted: 12 34 567.89 ok: true

Index

Examples

Constants

View Source
const NoSeparator = rune(0)

NoSeparator represents the absence of a separator and is the 0 rune.

Variables

This section is empty.

Functions

func IsNormalized

func IsNormalized[T bytestr](decimal T) bool

IsNormalized checks if a decimal string is normalized. A normalized decimal string adheres to the following rules:

  • May start with a '-' (negative sign).
  • Must be followed by one or more digits.
  • If a '.' is present, it must be followed by one or more digits.
  • Cannot start with '0' unless the integer part is exactly 0.
  • Cannot have trailing zeros after the '.' (e.g., "123.000" -> false).
  • Cannot have a trailing '.' (e.g., "123." -> false).
  • The string cannot be empty.
Example
fmt.Println(IsNormalized("-123.45"))
fmt.Println(IsNormalized("1 234.5"))
Output:

true
false

func Normalize

func Normalize[T bytestr](decimal T) (normalized T)

Normalize returns a normalized decimal string. A normalized decimal string adheres to the following rules:

  • May start with a '-' (negative sign).
  • Is followed by one or more digits.
  • If a '.' is present, it is followed by one or more digits (e.g., "123." -> "123").
  • Cannot start with '0' unless the integer part is exactly 0 (e.g., "0123.4" -> "123.4").
  • Cannot have trailing zeros after the '.' (e.g., "123.000" -> "123").
  • Cannot have a trailing '.' (e.g., "123." -> "123").
Example
fmt.Println(Normalize(" - 1 234,50 "))
fmt.Println(Normalize("12 345."))
Output:

-1234.5
12345

func NormalizeCheck

func NormalizeCheck[T bytestr](decimal T) (normalized T, ok bool)

NormalizeCheck returns a normalized decimal string and a boolean. The boolean `ok` is true if the input string was successfully normalized; otherwise, it is false, indicating the input string is unchanged.

Types

type DecimalFormat

type DecimalFormat struct {
	Point    rune
	Group    rune
	Standard bool
}

DecimalFormat describes the format of a decimal string.

  • Point: The decimal separator (or NoSeparator if absent).
  • Group: The grouping separator (or NoSeparator if absent).
  • Standard: True if grouping follows a standard pattern (e.g., groups of 3 digits), False if it uses a non-standard pattern (e.g., 3 digits then 2 digits).

func DetectFormat

func DetectFormat[T bytestr](decimal T) (df DecimalFormat, ok bool)

DetectFormat detects the decimal format of a string. It returns the detected DecimalFormat and a boolean indicating success. The boolean `ok` is false if the string does not contain a valid decimal format or if the format is ambiguous. If it is impossible to determine whether the grouping is standard or non-standard, it defaults to standard.

Example
df, ok := DetectFormat("1 234,56")
if !ok {
	fmt.Println("not a decimal")
}
fmt.Println(df)
Output:

{`,`, ` `, standard}

func (DecimalFormat) Convert

func (df DecimalFormat) Convert(decimal string) (new string, ok bool)

Convert converts a decimal string to a formatted decimal string using the specified DecimalFormat. If the input string is not a valid decimal string, it returns "0" and false. The input string does not need to be a normalized decimal string. The output string is formatted based on the following rules:

  • Grouping separators are inserted every 3 or 2 digits (depending on `df.Standard`).
  • A custom decimal separator (`df.Point`) is used.
  • Negative numbers retain their '-' sign. If + is present, it is removed.
Example
df := DecimalFormat{Point: ',', Group: ' ', Standard: true}
new, ok := df.Convert("123456789.123")
if !ok {
	fmt.Println("not a decimal")
}
fmt.Println(new)
Output:

123 456 789,123

func (DecimalFormat) String

func (df DecimalFormat) String() string

String returns a string representation of the DecimalFormat, formatted as {`<Point>`, `<Group>`, <standard|non-standard>}.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL