我尝试编写一个文化感知的字符串替换方法:
public static string Replace(string text, string oldValue, string newValue)
{
int index = text.IndexOf(oldValue, StringComparison.CurrentCulture);
return index >= 0
? text.Substring(0, index) + newValue + text.Substring(index + oldValue.Length)
: text;
}
但是,它无法正确处理Unicode组合字符:
// \u0301 is Combining Acute Accent
Console.WriteLine(Replace("déf", "é", "o")); // 1. CORRECT: dof
Console.WriteLine(Replace("déf", "e\u0301", "o")); // 2. INCORRECT: do
Console.WriteLine(Replace("de\u0301f", "é", "o")); // 3. INCORRECT: dóf
为了修复我的代码,我需要知道在第二个例子中,String.IndexOf
只匹配了一个字符 (é
),即使它搜索了两个字符 (e\u0301
)。同样的,我需要知道在第三个例子中,String.IndexOf
匹配了两个字符 (e\u0301
),即使它只搜索了一个字符 (é
)。如何确定
String.IndexOf
实际匹配的子字符串长度?
注意: 对于 text
和 oldValue
执行 Unicode 标准化(正如 James Keesey 建议的那样)可以容纳组合字符,但连字仍然是一个问题:Console.WriteLine(Replace("œf", "œ", "i")); // 4. CORRECT: if
Console.WriteLine(Replace("œf", "oe", "i")); // 5. INCORRECT: i
Console.WriteLine(Replace("oef", "œ", "i")); // 6. INCORRECT: ief
String.IndexOf
必须知道它匹配了多少个字符,但我很惊讶居然没有(明显的?)方法可以获取到这些信息。 - Michael LiuoldValue
更长。我们可能应该获得最长的可能匹配。 - usrfor (int length = 1; length < text.Length - index; length++)
应该改为for (int length = 1; length <= text.Length - index; length++)
- 例如,如果text.Length
是 3,index
是 2,则循环不执行任何操作,但它应该迭代一次。 - Jim W says reinstate Monica