Smarter Translation Memory: Matching Across Placeholder Formats
By Edouard · April 20, 2026
Translation Memory is one of the most powerful features in WebTranslateIt. When you’ve already translated a sentence in one project, TM finds it and suggests the same translation in another — saving time and ensuring consistency.
But there’s been a long-standing gap: what happens when the same English text uses different placeholder formats across projects?
The Problem
Consider a mobile app with Android, iOS, and web versions. All three projects contain the same sentence:
- Android:
I have %1$s dogs - iOS:
I have %@ dogs - Web (Rails):
I have %{count} dogs
These are the same sentence. A translator who translated the Android version shouldn’t have to translate it again for iOS or web. But until now, TM couldn’t match them — the placeholder syntax made each string look different at the byte level.
The same problem occurred with HTML entity encoding. One project might store Save & Continue while another stores Save & Continue. Same text, no TM match.
The Solution
We’ve added normalized TM matching — a new layer in the suggestion engine that strips placeholders and decodes entities before comparing strings. Here’s how it works:
Normalization: When comparing source texts, we decode HTML entities and strip all common placeholder formats —
%{name},{{name}},%1$s,%d,%@,{0}, and more. The three strings above all normalize toI have dogs.Matching: Normalized text is stored alongside each translation, enabling fast exact lookups across projects regardless of placeholder format.
Placeholder Adaptation: When a normalized match is found, we don’t just show the raw translation from the other project. We detect the placeholders in both the source and matched strings, then swap them automatically. If the Android translation is
J'ai %1$s chiens, the suggestion for the Rails project showsJ'ai %{count} chiens— ready to use.
How It Appears
Normalized matches show up in the suggestion panel with the label “Normalized TM”, alongside your regular TM and machine translation suggestions. Click to apply, just like any other suggestion.
Batch Operations
The Translate using TM batch operation now also uses normalized matching. If you have 500 untranslated strings in a new iOS project and the same strings already exist translated in your Android project, running the batch operation will find and apply those translations — with placeholders automatically adapted to the correct format.
Supported Placeholder Formats
Normalized matching handles the most common formats used across platforms:
| Format | Example | Platforms |
|---|---|---|
%{name} |
%{count} |
Ruby, Python |
{{name}} |
{{count}} |
Mustache, Handlebars, Angular |
{name} |
{count} |
Java MessageFormat, .NET |
%1$s, %2$d |
%1$s |
Android, Java |
%s, %d, %f |
%d |
C, Objective-C |
%@ |
%@ |
iOS (Swift/ObjC) |
{0}, {1} |
{0} |
Java, .NET positional |
HTML entities (&, <, >, ", ', numeric entities) are also decoded for matching.
What About Edge Cases?
- Different placeholder counts: If the source has 2 placeholders but the match has 3, we skip adaptation and show the suggestion as-is. The translator can adapt manually using the variable pills.
- Plural strings: Plural forms (hashes) are matched but not adapted — the translator reviews these.
- Ranking: Normalized matches rank below exact TM matches, so a perfect match from within your own project always appears first.
Getting Started
This feature is enabled automatically for all projects. No configuration needed. If you have multiple projects with the same content in different placeholder formats, you should start seeing normalized TM suggestions immediately.
For existing translations, we’ve backfilled the normalized text index — so matches work retroactively, not just for new strings.
















