Skip to content

Smart Strings

Smart Strings provide dynamic text formatting with variables, pluralization, gender agreement, and locale-aware formatting.

PatternExampleResult
PositionalHello {0}!Hello World!
NamedHello {name}!Hello John!

Positional Arguments:

csharp
// Template: "{0} scored {1} points"
string result = Localization.Get("score.message", "John", 100);
// Result: "John scored 100 points"

Named Arguments (via Dictionary):

csharp
var args = new Dictionary<string, object>
{
    { "player", "John" },
    { "score", 100 }
};
string result = SmartStringParser.Parse("{player} scored {score} points", args);
// Result: "John scored 100 points"

Syntax: {variable:plural:category=text|category=text}

Use # as placeholder for the number.

csharp
// Template: "{0:plural:one=# item|other=# items}"

SmartStringParser.Parse("{0:plural:one=# item|other=# items}", 1);
// Result: "1 item"

SmartStringParser.Parse("{0:plural:one=# item|other=# items}", 5);
// Result: "5 items"

CLDR Plural Categories:

CategoryUsed By
zeroArabic, Latvian, Welsh
oneEnglish, German, Spanish, French
twoArabic, Hebrew, Slovenian
fewRussian, Czech, Polish
manyRussian, Polish, Arabic
otherAll languages (required fallback)

Complex Example (Russian):

{0:plural:one=# яблоко|few=# яблока|many=# яблок|other=# яблока}

Syntax: {variable:male=text|female=text|other=text}

csharp
// Template: "{0:male=He|female=She|other=They} logged in"

SmartStringParser.Parse("{0:male=He|female=She|other=They} logged in", "female");
// Result: "She logged in"

Syntax: {variable:true=text|false=text}

csharp
// Template: "Status: {0:true=Online|false=Offline}"

SmartStringParser.Parse("Status: {0:true=Online|false=Offline}", true);
// Result: "Status: Online"

Uses .NET format specifiers with locale-aware formatting.

FormatExampleResult (en-US)Result (de-DE)
N0{0:N0}1,234,5671.234.567
N2{0:N2}1,234.561.234,56
C{0:C}$19.9919,99 €
P{0:P}85.50%85,50 %
csharp
// Template: "Score: {0:N0}"
SmartStringParser.Parse("Score: {0:N0}", 1234567);
// Result: "Score: 1,234,567"

// Template: "Price: {0:C}"
SmartStringParser.Parse("Price: {0:C}", 19.99m);
// Result: "Price: $19.99" (or locale equivalent)
FormatDescriptionExample (en-US)
dShort date1/15/2025
DLong dateWednesday, January 15, 2025
csharp
// Template: "Date: {0:d}"
SmartStringParser.Parse("Date: {0:d}", DateTime.Now);
// Result: "Date: 1/15/2025"

Select Formatter

Added in v1.1.0

Syntax: {variable:select:key=text|key=text|other=text}

Map values to specific text. Supports exact match, range match, and other fallback.

csharp
// Exact match
SmartStringParser.Parse("{0:select:warrior=Warrior Class|mage=Mage Class|other=Unknown}", "warrior");
// Result: "Warrior Class"

// Range match (numeric values)
SmartStringParser.Parse("{0:select:1-10=Low Level|11-50=Mid Level|other=High Level}", 7);
// Result: "Low Level"

// Mixed exact + range with # replacement
SmartStringParser.Parse("{0:select:0=None|1-5=# items (few)|other=# items (many)}", 3);
// Result: "3 items (few)"

Ordinal Plurals

Added in v1.1.0

Syntax: {variable:ordinal:one=text|two=text|few=text|other=text}

Format ordinal numbers (1st, 2nd, 3rd, 4th...) using CLDR ordinal rules.

csharp
SmartStringParser.Parse("{0:ordinal:one=#st|two=#nd|few=#rd|other=#th}", 1);  // "1st"
SmartStringParser.Parse("{0:ordinal:one=#st|two=#nd|few=#rd|other=#th}", 2);  // "2nd"
SmartStringParser.Parse("{0:ordinal:one=#st|two=#nd|few=#rd|other=#th}", 3);  // "3rd"
SmartStringParser.Parse("{0:ordinal:one=#st|two=#nd|few=#rd|other=#th}", 11); // "11th"
SmartStringParser.Parse("{0:ordinal:one=#st|two=#nd|few=#rd|other=#th}", 21); // "21st"

List Formatter

Added in v1.1.0

Syntax: {variable:list:separator|lastSeparator}

Join collections with configurable separators.

csharp
var items = new[] { "sword", "shield", "potion" };
SmartStringParser.Parse("{0:list:, |, and }", items);
// Result: "sword, shield, and potion"

SmartStringParser.Parse("{0:list: / }", items);
// Result: "sword / shield / potion"

Escaped Characters

Added in v1.1.0

Use backslash escapes in format specs when you need literal | or = characters:

EscapeResult
|Literal pipe
\=Literal equals
\\Literal backslash
csharp
SmartStringParser.Parse("{0:plural:one=1\|2 items|other=# items}", 1);
// Result: "1|2 items"

Template Caching

Added in v1.1.0

Templates are automatically cached after first parse. Use ClearCache() when localization data changes significantly:

csharp
SmartStringParser.ClearCache();

Validate templates before deployment:

csharp
bool isValid = SmartStringParser.Validate(template, out string[] errors);
if (!isValid)
{
    foreach (var error in errors)
    {
        Debug.LogError($"Template error: {error}");
    }
}

Get all variable names from a template:

csharp
string[] vars = SmartStringParser.ExtractVariables("{player} scored {score} points");
// Returns: ["player", "score"]

Professional Unity Development Tools