emailnormalizer

package module
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Mar 12, 2026 License: MIT Imports: 3 Imported by: 0

README

go-email-normalizer

Fork of dimuska139/go-email-normalizer

This is Golang library for providing a canonical representation of email address. It allows to prevent multiple signups. go-email-normalizer contains some popular providers but you can easily append others.

Usage

Normalize

Normalize returns the canonical form of an email address as a plain string.

package main

import (
	"fmt"
	"strings"
	normalizer "github.com/bobadilla-tech/go-email-normalizer"
)

type customRule struct{}

func (rule *customRule) ProcessUsername(username string) string {
	return strings.Replace(username, "-", "", -1)
}

func (rule *customRule) ProcessDomain(domain string) string {
	return domain
}

func main() {
	n := normalizer.NewNormalizer()
	fmt.Println(n.Normalize("vasya+pupkin@gmail.com")) // vasya@gmail.com
	fmt.Println(n.Normalize("t.e-St+vasya@gmail.com")) // te-st@gmail.com
	fmt.Println(n.Normalize("John+Brown@yahoo.com"))   // john+brown@yahoo.com
	fmt.Println(n.Normalize("John-Brown@yahoo.com"))   // john@yahoo.com
	fmt.Println(n.Normalize("t.e-St+@googlemail.com")) // te-st@gmail.com
	fmt.Println(n.Normalize("t.e-St+@google.com"))     // te-st@google.com

	n.AddRule("customrules.com", &customRule{})
	fmt.Println(n.Normalize(" tE-S-t@CustomRules.com.")) // tESt@customrules.com
}
Normalize2

Normalize2 accepts any string, validates it as an email address using net/mail.ParseAddress, and returns a NormalizeResult paired with an error. If the input is not a valid email address, the result is zero-valued and the error is non-nil. When the call succeeds, the result pairs the canonical address with a list of every transformation applied, in order. Each Change value appears at most once.

n := normalizer.NewNormalizer()

result, err := n.Normalize2("First.Last+tag@googlemail.com")
if err != nil {
	log.Fatal(err)
}
fmt.Println(result.Normalized) // firstlast@gmail.com
fmt.Println(result.Changes)
// [lowercase removed_dots removed_plus_tag canonicalized_domain]

result, err = n.Normalize2("User.Name_test-sub+spam@protonmail.com")
if err != nil {
	log.Fatal(err)
}
fmt.Println(result.Normalized) // usernametestsub@protonmail.com
fmt.Println(result.Changes)
// [lowercase removed_dots removed_underscores removed_hyphens removed_plus_tag]

result, err = n.Normalize2("Test+User-Name@ya.ru")
if err != nil {
	log.Fatal(err)
}
fmt.Println(result.Normalized) // testuser.name@yandex.ru
fmt.Println(result.Changes)
// [lowercase removed_plus_signs replaced_hyphens_with_dots canonicalized_domain]

// Invalid input — error is returned, result is zero-valued.
_, err = n.Normalize2("notanemail")
fmt.Println(err) // invalid email address: ...
Change values
Constant Value Produced by
ChangeTrimmedWhitespace trimmed_whitespace leading/trailing whitespace stripped
ChangeRemovedTrailingDot removed_trailing_dot trailing dot stripped from raw input
ChangeLowercase lowercase username or domain uppercased → lowercased
ChangeRemovedDots removed_dots dots removed from username (Google, Protonmail)
ChangeRemovedUnderscores removed_underscores underscores removed from username (Protonmail)
ChangeRemovedHyphens removed_hyphens hyphens removed from username (Protonmail)
ChangeReplacedHyphensWithDots replaced_hyphens_with_dots hyphens replaced with dots in username (Yandex)
ChangeRemovedPlusTag removed_plus_tag +tag subaddress stripped (Google, Apple, Fastmail, Protonmail)
ChangeRemovedPlusSigns removed_plus_signs all + characters removed (Microsoft, Rackspace, Rambler, Yandex, Zoho)
ChangeRemovedSubaddress removed_subaddress -tag subaddress stripped (Yahoo)
ChangeCanonicalisedDomain canonicalized_domain domain rewritten to canonical form (e.g. googlemail.com → gmail.com)

Supported providers

  • Apple
  • Fastmail
  • Google
  • Microsoft
  • Protonmail
  • Rackspace
  • Rambler
  • Yahoo
  • Yandex
  • Zoho

Also you can integrate other rules using AddRule function (see an example above)

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AppleRule

type AppleRule struct {
}

AppleRule : email normalization rule for Apple

func (*AppleRule) ProcessDomain

func (rule *AppleRule) ProcessDomain(domain string) string

func (*AppleRule) ProcessDomainWithChanges

func (rule *AppleRule) ProcessDomainWithChanges(domain string) (string, []Change)

func (*AppleRule) ProcessUsername

func (rule *AppleRule) ProcessUsername(username string) string

func (*AppleRule) ProcessUsernameWithChanges

func (rule *AppleRule) ProcessUsernameWithChanges(username string) (string, []Change)

type Change

type Change string

Change is a string enum identifying a single transformation applied to an email address during normalization. It is returned by Normalize2.

const (
	// ChangeTrimmedWhitespace is applied when leading or trailing whitespace is
	// removed from the raw input.
	ChangeTrimmedWhitespace Change = "trimmed_whitespace"

	// ChangeRemovedTrailingDot is applied when one or more trailing dots are
	// stripped from the raw input.
	ChangeRemovedTrailingDot Change = "removed_trailing_dot"

	// ChangeLowercase is applied when the username or domain contains uppercase
	// letters that are converted to lower case.
	ChangeLowercase Change = "lowercase"

	// ChangeRemovedDots is applied when dot characters are removed from the
	// username (e.g. Google, Protonmail).
	ChangeRemovedDots Change = "removed_dots"

	// ChangeRemovedUnderscores is applied when underscore characters are removed
	// from the username (e.g. Protonmail).
	ChangeRemovedUnderscores Change = "removed_underscores"

	// ChangeRemovedHyphens is applied when hyphen characters are removed from
	// the username (e.g. Protonmail).
	ChangeRemovedHyphens Change = "removed_hyphens"

	// ChangeReplacedHyphensWithDots is applied when hyphen characters in the
	// username are replaced with dots (e.g. Yandex).
	ChangeReplacedHyphensWithDots Change = "replaced_hyphens_with_dots"

	// ChangeRemovedPlusTag is applied when a plus-sign subaddress ("+tag") is
	// stripped from the end of the username (e.g. Google, Apple, Fastmail,
	// Protonmail).
	ChangeRemovedPlusTag Change = "removed_plus_tag"

	// ChangeRemovedPlusSigns is applied when plus-sign characters are removed
	// from the username without subaddress semantics — every "+" is deleted
	// regardless of position (e.g. Microsoft, Rackspace, Rambler, Yandex, Zoho).
	ChangeRemovedPlusSigns Change = "removed_plus_signs"

	// ChangeRemovedSubaddress is applied when a dash-delimited subaddress
	// ("-tag") is stripped from the end of the username (e.g. Yahoo).
	ChangeRemovedSubaddress Change = "removed_subaddress"

	// ChangeCanonicalisedDomain is applied when the domain is rewritten to its
	// canonical form (e.g. googlemail.com → gmail.com, me.com → icloud.com,
	// ya.ru → yandex.ru).
	ChangeCanonicalisedDomain Change = "canonicalized_domain"
)

type FastmailRule

type FastmailRule struct {
}

FastmailRule : email normalization rule for Fastmail

func (*FastmailRule) ProcessDomain

func (rule *FastmailRule) ProcessDomain(domain string) string

func (*FastmailRule) ProcessDomainWithChanges

func (rule *FastmailRule) ProcessDomainWithChanges(domain string) (string, []Change)

func (*FastmailRule) ProcessUsername

func (rule *FastmailRule) ProcessUsername(username string) string

func (*FastmailRule) ProcessUsernameWithChanges

func (rule *FastmailRule) ProcessUsernameWithChanges(username string) (string, []Change)

type GoogleRule

type GoogleRule struct {
}

GoogleRule : email normalization rule for Google

func (*GoogleRule) ProcessDomain

func (rule *GoogleRule) ProcessDomain(domain string) string

func (*GoogleRule) ProcessDomainWithChanges

func (rule *GoogleRule) ProcessDomainWithChanges(domain string) (string, []Change)

func (*GoogleRule) ProcessUsername

func (rule *GoogleRule) ProcessUsername(username string) string

func (*GoogleRule) ProcessUsernameWithChanges

func (rule *GoogleRule) ProcessUsernameWithChanges(username string) (string, []Change)

type MicrosoftRule

type MicrosoftRule struct {
}

MicrosoftRule : email normalization rule for Microsoft

func (*MicrosoftRule) ProcessDomain

func (rule *MicrosoftRule) ProcessDomain(domain string) string

func (*MicrosoftRule) ProcessDomainWithChanges

func (rule *MicrosoftRule) ProcessDomainWithChanges(domain string) (string, []Change)

func (*MicrosoftRule) ProcessUsername

func (rule *MicrosoftRule) ProcessUsername(username string) string

func (*MicrosoftRule) ProcessUsernameWithChanges

func (rule *MicrosoftRule) ProcessUsernameWithChanges(username string) (string, []Change)

type NormalizeResult

type NormalizeResult struct {
	// Normalized is the canonical form of the email address.
	Normalized string

	// Changes lists every transformation that was applied, in the order they
	// were first detected. Each Change value appears at most once.
	Changes []Change
}

NormalizeResult is the return value of Normalize2.

type Normalizer

type Normalizer struct {
	// contains filtered or unexported fields
}

Normalizer : main library object for normalization emails

func NewNormalizer

func NewNormalizer() *Normalizer

NewNormalizer : creates Normalizer instance

func (*Normalizer) AddRule

func (n *Normalizer) AddRule(domain string, strategy NormalizingRule)

AddRule : appends custom normalization rule

func (*Normalizer) Normalize

func (n *Normalizer) Normalize(email string) string

Normalize : converts email to canonical form

func (*Normalizer) Normalize2

func (n *Normalizer) Normalize2(email string) (NormalizeResult, error)

Normalize2 converts any input string to a canonical email address and returns a NormalizeResult that includes both the normalized address and every transformation applied.

Unlike Normalize, Normalize2 validates the input using net/mail.ParseAddress. If the input is not a valid email address, a zero-valued NormalizeResult and a non-nil error (wrapping the underlying parse error) are returned.

Rules registered via AddRule that only implement NormalizingRule (not NormalizingRuleWithChanges) are still fully supported — the normalized address will be correct, but per-rule changes will not be reported. Pre-processing changes (whitespace trimming, trailing-dot removal, domain lowercasing) are always tracked regardless of the rule type.

type NormalizingRule

type NormalizingRule interface {
	ProcessUsername(string) string
	ProcessDomain(string) string
}

NormalizingRule : interface for all email normalization rules

type NormalizingRuleWithChanges

type NormalizingRuleWithChanges interface {
	NormalizingRule
	ProcessUsernameWithChanges(username string) (result string, changes []Change)
	ProcessDomainWithChanges(domain string) (result string, changes []Change)
}

NormalizingRuleWithChanges is an optional extension of NormalizingRule. Rules that implement it allow Normalize2 to report the individual transformations applied to the username and domain. Rules added via AddRule that only satisfy NormalizingRule are still supported by Normalize2 — they will not report per-rule changes, but global pre-processing changes (whitespace trimming, trailing-dot removal, domain lowercasing) are always tracked.

type ProtonmailRule

type ProtonmailRule struct {
}

ProtonmailRule : email normalization rule for Protonmail

func (*ProtonmailRule) ProcessDomain

func (rule *ProtonmailRule) ProcessDomain(domain string) string

func (*ProtonmailRule) ProcessDomainWithChanges

func (rule *ProtonmailRule) ProcessDomainWithChanges(domain string) (string, []Change)

func (*ProtonmailRule) ProcessUsername

func (rule *ProtonmailRule) ProcessUsername(username string) string

func (*ProtonmailRule) ProcessUsernameWithChanges

func (rule *ProtonmailRule) ProcessUsernameWithChanges(username string) (string, []Change)

type RackspaceRule

type RackspaceRule struct {
}

RackspaceRule : email normalization rule for Rackspace

func (*RackspaceRule) ProcessDomain

func (rule *RackspaceRule) ProcessDomain(domain string) string

func (*RackspaceRule) ProcessDomainWithChanges

func (rule *RackspaceRule) ProcessDomainWithChanges(domain string) (string, []Change)

func (*RackspaceRule) ProcessUsername

func (rule *RackspaceRule) ProcessUsername(username string) string

func (*RackspaceRule) ProcessUsernameWithChanges

func (rule *RackspaceRule) ProcessUsernameWithChanges(username string) (string, []Change)

type RamblerRule

type RamblerRule struct {
}

RamblerRule : email normalization rule for Rambler

func (*RamblerRule) ProcessDomain

func (rule *RamblerRule) ProcessDomain(domain string) string

func (*RamblerRule) ProcessDomainWithChanges

func (rule *RamblerRule) ProcessDomainWithChanges(domain string) (string, []Change)

func (*RamblerRule) ProcessUsername

func (rule *RamblerRule) ProcessUsername(username string) string

func (*RamblerRule) ProcessUsernameWithChanges

func (rule *RamblerRule) ProcessUsernameWithChanges(username string) (string, []Change)

type YahooRule

type YahooRule struct {
}

YahooRule : email normalization rule for Yahoo

func (*YahooRule) ProcessDomain

func (rule *YahooRule) ProcessDomain(domain string) string

func (*YahooRule) ProcessDomainWithChanges

func (rule *YahooRule) ProcessDomainWithChanges(domain string) (string, []Change)

func (*YahooRule) ProcessUsername

func (rule *YahooRule) ProcessUsername(username string) string

func (*YahooRule) ProcessUsernameWithChanges

func (rule *YahooRule) ProcessUsernameWithChanges(username string) (string, []Change)

type YandexRule

type YandexRule struct {
}

YandexRule : email normalization rule for Yandex

func (*YandexRule) ProcessDomain

func (rule *YandexRule) ProcessDomain(domain string) string

func (*YandexRule) ProcessDomainWithChanges

func (rule *YandexRule) ProcessDomainWithChanges(domain string) (string, []Change)

func (*YandexRule) ProcessUsername

func (rule *YandexRule) ProcessUsername(username string) string

func (*YandexRule) ProcessUsernameWithChanges

func (rule *YandexRule) ProcessUsernameWithChanges(username string) (string, []Change)

type ZohoRule

type ZohoRule struct {
}

ZohoRule : email normalization rule for Zoho

func (*ZohoRule) ProcessDomain

func (rule *ZohoRule) ProcessDomain(domain string) string

func (*ZohoRule) ProcessDomainWithChanges

func (rule *ZohoRule) ProcessDomainWithChanges(domain string) (string, []Change)

func (*ZohoRule) ProcessUsername

func (rule *ZohoRule) ProcessUsername(username string) string

func (*ZohoRule) ProcessUsernameWithChanges

func (rule *ZohoRule) ProcessUsernameWithChanges(username string) (string, []Change)

Jump to

Keyboard shortcuts

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