Similar to T207623, a difference between string.gsub and mw.ustring.gsub:
local t = setmetatable({ a = '1' }, { __index = { b = '2' } }) mw.log('string.gsub', string.gsub('ab', '.', t)) -- return values: '12', 2 mw.log('mw.ustring.gsub', mw.ustring.gsub('ab', '.', t)) -- return values: '1b', 2
It looks like mw.ustring.gsub is not replacing 'b' because it does not find a field with that key in t, and it is doing the equivalent of rawget (ignoring the __index metamethod, which would return '2' for 'b') rather than a normal field access.
I ran into this in Module:Ancient Greek (ALA-LC) on Wikipedia, where I was using the __index metamethod to switch between two tables mapping Greek characters to their transliteration in a given transliteration system.