我想创建一个忽略重音的正则表达式。
例如:
string s = "I am an old élephant";
string pattern = "elephant";
bool result = new Regex(pattern, RegexOptions.CultureInvariant).IsMatch(s);
我测试时的文化是:
System.Globalization.CultureInfo.CurrentCulture = Fr-fr
所以我希望这段代码找到一个匹配但不会。
有没有一种简单的方法来获得匹配?
我正在尝试创建一个StringReplace重载方法,用大象替换élèphânt等等。
答案 0 :(得分:3)
使用以下方法:
public string removeDiacritics(string str)
{
var sb = new StringBuilder();
foreach (char c in str.Normalize(NormalizationForm.FormD))
{
if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
{
sb.Append(c);
}
}
return sb.ToString().Normalize(NormalizationForm.FormC);
}
然后它可以工作
string s = "I am an old élephant";
string pattern = "elephant";
bool result = new Regex(pattern, RegexOptions.IgnoreCase).IsMatch(removeDiacritics(s)); //true
如果你需要更换一些东西,例如迭代(向后)通过matchcollection并根据每个匹配的索引编辑原始字符串。
解释:(我正在使用“我是一个古老的élephant”字符串)
让我们将原始字符串的所有字符写入列表:
foreach (char c in str)
{
chars1.Add(c);
}
如您所见,char被定义为unicode char 233或00E9(参见http://unicode-table.com/de/#00E9)
此处解释了规范化 https://msdn.microsoft.com/en-us/library/system.text.normalizationform(v=vs.110).aspx
正如文件所述: 表格D:
Indicates that a Unicode string is normalized using full canonical decomposition.
这意味着charé被“拆分”为e和重音字符。
要检查一下,让我们输出规范化字符串的字符:
List<char> chars2 = new List<char>();
foreach(char c in str.Normalize(NormalizationForm.FormD))
{
chars2.Add(c);
}
如手表所示,é现已归一化为2个字符(101(\ u0065)+ 769(\ u0301))
现在我们必须消除这些口音: 遍历规范化字符串的所有字符,如果它是“NonSpacingMark”,则将其添加到StringBuilder。
MSDN: https://msdn.microsoft.com/en-us/library/system.globalization.unicodecategory(v=vs.110).aspx
NonSpacingMark
表示基本字符修改的非间距字符。 由Unicode标识“Mn”表示(标记,非间距)。该 价值是5.
最后,为了确保所有其他字符(现在在字符串中定义为2或3个字符)被“转换”为unicode字符符号,我们必须将新字符串规范化为FormC。
MSDN: FormC:
表示使用完整规范标准化Unicode字符串 分解,然后用它们替换序列 主要复合材料,如果可能的话。
答案 1 :(得分:1)
您正在指定Culture In 变体正则表达式。这意味着您的文化被忽略。所以你要么必须删除选项......
bool result = new Regex(pattern).IsMatch(s);
...或者如果您想独立于文化,请扩展您的模式:
string pattern = "[eé]lephant";
答案 2 :(得分:0)
如果要使用正则表达式,可以使用\P{L}
表示给定的unicode字符是一个字母。
string s = "I am an old ùûüÿàâçéèêëïîô";
string pattern = @"(\p{L})";
var regex = new Regex(pattern);
var result = regex.Replace(s, @"$1");
Console.WriteLine(result);//I am an old uuuyaaceeeeiio