我尝试转换一些法裔加拿大的字符串,基本上,我想能够去掉字母上的法语重音标记并保留字母本身。(例如将
é
转换为 e
,因此 crème brûlée
将变为 creme brulee
)最好的方法是什么?é
转换为 e
,因此 crème brûlée
将变为 creme brulee
)最好的方法是什么?对于仅需要删除加拿大法语口音符号的情况,这里提供了一种使用正则表达式而非硬编码转换和For/Next循环的替代方法。根据您的需求,它可以被压缩为单行代码;但是,我将其添加到扩展类中以便于重复使用。
Visual Basic
Imports System.Text
Imports System.Text.RegularExpressions
Public MustInherit Class StringExtension
Public Shared Function RemoveDiacritics(Text As String) As String
Return New Regex("\p{Mn}", RegexOptions.Compiled).Replace(Text.Normalize(NormalizationForm.FormD), String.Empty)
End Function
End Class
实现
Private Shared Sub DoStuff()
MsgBox(StringExtension.RemoveDiacritics(inputString))
End Sub
c#
using System.Text;
using System.Text.RegularExpressions;
namespace YourApplication
{
public abstract class StringExtension
{
public static string RemoveDiacritics(string Text)
{
return new Regex(@"\p{Mn}", RegexOptions.Compiled).Replace(Text.Normalize(NormalizationForm.FormD), string.Empty);
}
}
}
实现
private static void DoStuff()
{
MessageBox.Show(StringExtension.RemoveDiacritics(inputString));
}
输入: äáčďěéíľľňôóřŕšťúůýž ÄÁČĎĚÉÍĽĽŇÔÓŘŔŠŤÚŮÝŽ ÖÜË łŁđĐ ţŢşŞçÇ øı
输出: aacdeeillnoorrstuuyz AACDEEILLNOORRSTUUYZ OUE łŁđĐ tTsScC øı
我包括了一些不会被转换的字符,以帮助可视化处理意外输入时会发生什么。
如果您需要将其他类型的字符(如波兰语中的ł和Ł)也转换,那么根据您的需求,考虑将使用CodePagesEncodingProvider
的此答案 (适用于.NET Core)融入到您的解决方案中。
如果有人认为Lucene.Net对于去除变音符号来说过于复杂,我找到了这个小型库,它可以为您使用ASCII转换。
以下是我如何在所有的.NET程序中将有变音符号的字符替换为没有变音符号的字符:
C#:
//Transforms the culture of a letter to its equivalent representation in the 0-127 ascii table, such as the letter 'é' is substituted by an 'e'
public string RemoveDiacritics(string s)
{
string normalizedString = null;
StringBuilder stringBuilder = new StringBuilder();
normalizedString = s.Normalize(NormalizationForm.FormD);
int i = 0;
char c = '\0';
for (i = 0; i <= normalizedString.Length - 1; i++)
{
c = normalizedString[i];
if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
{
stringBuilder.Append(c);
}
}
return stringBuilder.ToString().ToLower();
}
VB .NET:
'Transforms the culture of a letter to its equivalent representation in the 0-127 ascii table, such as the letter "é" is substituted by an "e"'
Public Function RemoveDiacritics(ByVal s As String) As String
Dim normalizedString As String
Dim stringBuilder As New StringBuilder
normalizedString = s.Normalize(NormalizationForm.FormD)
Dim i As Integer
Dim c As Char
For i = 0 To normalizedString.Length - 1
c = normalizedString(i)
If CharUnicodeInfo.GetUnicodeCategory(c) <> UnicodeCategory.NonSpacingMark Then
stringBuilder.Append(c)
End If
Next
Return stringBuilder.ToString().ToLower()
End Function
这是 VB 版本(适用于希腊语):
导入 System.Text
导入 System.Globalization
Public Function RemoveDiacritics(ByVal s As String)
Dim normalizedString As String
Dim stringBuilder As New StringBuilder
normalizedString = s.Normalize(NormalizationForm.FormD)
Dim i As Integer
Dim c As Char
For i = 0 To normalizedString.Length - 1
c = normalizedString(i)
If CharUnicodeInfo.GetUnicodeCategory(c) <> UnicodeCategory.NonSpacingMark Then
stringBuilder.Append(c)
End If
Next
Return stringBuilder.ToString()
End Function
public static string RemoveAccents(this string source)
{
//8 bit characters
byte[] b = Encoding.GetEncoding(1251).GetBytes(source);
// 7 bit characters
string t = Encoding.ASCII.GetString(b);
Regex re = new Regex("[^a-zA-Z0-9]=-_/");
string c = re.Replace(t, " ");
return c;
}
using MMLib.RapidPrototyping.Generators;
public void ExtensionsExample()
{
string target = "aácčeéií";
Assert.AreEqual("aacceeii", target.RemoveDiacritics());
}
Imports System.Text
Imports System.Globalization
Public Function DECODE(ByVal x As String) As String
Dim sb As New StringBuilder
For Each c As Char In x.Normalize(NormalizationForm.FormD).Where(Function(a) CharUnicodeInfo.GetUnicodeCategory(a) <> UnicodeCategory.NonSpacingMark)
sb.Append(c)
Next
Return sb.ToString()
End Function
Encoding.ASCII.GetString(Encoding.GetEncoding(1251).GetBytes(text));
我非常喜欢azrafe7提供的简洁而实用的代码。因此,我稍微改变了一下,将其转换为扩展方法:
public static class StringExtensions
{
public static string RemoveDiacritics(this string text)
{
const string SINGLEBYTE_LATIN_ASCII_ENCODING = "ISO-8859-8";
if (string.IsNullOrEmpty(text))
{
return string.Empty;
}
return Encoding.ASCII.GetString(
Encoding.GetEncoding(SINGLEBYTE_LATIN_ASCII_ENCODING).GetBytes(text));
}
}
[a-zA-Z0-9_]
。而对于我们的情况,确实需要进行快速搜索。 - Mike de Klerk