フランス系カナダ人の文字列を変換しようとしていますが、基本的には、文字を維持したまま、文字のフランス語のアクセント記号を取り出せるようにしたいと考えています。(例: に変換するé
とe
、crème brûlée
になりますcreme brulee
)
これを達成するための最良の方法は何ですか?
フランス系カナダ人の文字列を変換しようとしていますが、基本的には、文字を維持したまま、文字のフランス語のアクセント記号を取り出せるようにしたいと考えています。(例: に変換するé
とe
、crème brûlée
になりますcreme brulee
)
これを達成するための最良の方法は何ですか?
私はこの方法を使用していませんが、Michael Kaplanは、発音区別符号の除去について説明している彼のブログ投稿(紛らわしいタイトル付き)で使用する方法を説明しています。間隔がありませんが、一部は他よりも間隔がありません)
static string RemoveDiacritics(string text)
{
var normalizedString = text.Normalize(NormalizationForm.FormD);
var stringBuilder = new StringBuilder(capacity: normalizedString.Length);
for (int i = 0; i < normalizedString.Length; i++)
{
char c = normalizedString[i];
var unicodeCategory = CharUnicodeInfo.GetUnicodeCategory(c);
if (unicodeCategory != UnicodeCategory.NonSpacingMark)
{
stringBuilder.Append(c);
}
}
return stringBuilder
.ToString()
.Normalize(NormalizationForm.FormC);
}
これは彼の以前の投稿のフォローアップであることに注意してください:発音区別符号の除去...
このアプローチでは、 String.Normalizeを使用して、入力文字列を構成グリフに分割し(基本的に、「基本」文字を発音区別符号から分離します)、結果をスキャンして基本文字のみを保持します。少し複雑ですが、実際には複雑な問題を見ています。
もちろん、フランス語に限定している場合は、@ David Dibbenが推奨するように、C ++ std::stringでアクセントとチルダを削除する方法の単純なテーブルベースのアプローチでうまくいく可能性があります。
これは私にとってはうまくいきました...
string accentedStr;
byte[] tempBytes;
tempBytes = System.Text.Encoding.GetEncoding("ISO-8859-8").GetBytes(accentedStr);
string asciiStr = System.Text.Encoding.UTF8.GetString(tempBytes);
クイック&ショート!
誰かが興味を持っている場合に備えて、私は似たようなものを探していて、次のように書き終えました:
public static string NormalizeStringForUrl(string name)
{
String normalizedString = name.Normalize(NormalizationForm.FormD);
StringBuilder stringBuilder = new StringBuilder();
foreach (char c in normalizedString)
{
switch (CharUnicodeInfo.GetUnicodeCategory(c))
{
case UnicodeCategory.LowercaseLetter:
case UnicodeCategory.UppercaseLetter:
case UnicodeCategory.DecimalDigitNumber:
stringBuilder.Append(c);
break;
case UnicodeCategory.SpaceSeparator:
case UnicodeCategory.ConnectorPunctuation:
case UnicodeCategory.DashPunctuation:
stringBuilder.Append('_');
break;
}
}
string result = stringBuilder.ToString();
return String.Join("_", result.Split(new char[] { '_' }
, StringSplitOptions.RemoveEmptyEntries)); // remove duplicate underscores
}
ここで見つけた別のバージョンに基づく拡張方法をよく使用します(C#(ascii)での文字の置き換えを参照)簡単な説明:
コード:
using System.Linq;
using System.Text;
using System.Globalization;
// namespace here
public static class Utility
{
public static string RemoveDiacritics(this string str)
{
if (null == str) return null;
var chars =
from c in str.Normalize(NormalizationForm.FormD).ToCharArray()
let uc = CharUnicodeInfo.GetUnicodeCategory(c)
where uc != UnicodeCategory.NonSpacingMark
select c;
var cleanStr = new string(chars.ToArray()).Normalize(NormalizationForm.FormC);
return cleanStr;
}
// or, alternatively
public static string RemoveDiacritics2(this string str)
{
if (null == str) return null;
var chars = str
.Normalize(NormalizationForm.FormD)
.ToCharArray()
.Where(c=> CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
.ToArray();
return new string(chars).Normalize(NormalizationForm.FormC);
}
}
ギリシャ語 (ISO)の CodePage はそれを行うことができます
このコードページに関する情報はSystem.Text.Encoding.GetEncodings()
. 詳細については、https ://msdn.microsoft.com/pt-br/library/system.text.encodinginfo.getencoding(v=vs.110).aspx を参照してください。
ギリシャ語 (ISO) のコードページは28597で、名前はiso-8859-7です。
コードに移動... \o/
string text = "Você está numa situação lamentável";
string textEncode = System.Web.HttpUtility.UrlEncode(text, Encoding.GetEncoding("iso-8859-7"));
//result: "Voce+esta+numa+situacao+lamentavel"
string textDecode = System.Web.HttpUtility.UrlDecode(textEncode);
//result: "Voce esta numa situacao lamentavel"
だから、この関数を書いて...
public string RemoveAcentuation(string text)
{
return
System.Web.HttpUtility.UrlDecode(
System.Web.HttpUtility.UrlEncode(
text, Encoding.GetEncoding("iso-8859-7")));
}
最初が名前で、2 番目が Encoding のコードページであるため、...Encoding.GetEncoding("iso-8859-7")
は と同等であることに注意してください。Encoding.GetEncoding(28597)
そのような質問は非常に多くの答えを得ることができますが、私の要件に合うものはありません:)周りには非常に多くの言語があり、他の人がFormCまたはFormDが問題を引き起こしていると述べているように、言語にとらわれない完全な解決策は実際には不可能です。
元の質問はフランス語に関連していたので、最も簡単な答えは確かに
public static string ConvertWesternEuropeanToASCII(this string str)
{
return Encoding.ASCII.GetString(Encoding.GetEncoding(1251).GetBytes(str));
}
1251 は、入力言語のエンコード コードに置き換える必要があります。
ただし、これは1文字のみを1文字に置き換えます。私もドイツ語を入力として作業しているので、手動で変換しました
public static string LatinizeGermanCharacters(this string str)
{
StringBuilder sb = new StringBuilder(str.Length);
foreach (char c in str)
{
switch (c)
{
case 'ä':
sb.Append("ae");
break;
case 'ö':
sb.Append("oe");
break;
case 'ü':
sb.Append("ue");
break;
case 'Ä':
sb.Append("Ae");
break;
case 'Ö':
sb.Append("Oe");
break;
case 'Ü':
sb.Append("Ue");
break;
case 'ß':
sb.Append("ss");
break;
default:
sb.Append(c);
break;
}
}
return sb.ToString();
}
最高のパフォーマンスは得られないかもしれませんが、少なくとも読み取りと拡張は非常に簡単です。正規表現はNO GOであり、文字/文字列よりもはるかに低速です。
スペースを削除する非常に簡単な方法もあります。
public static string RemoveSpace(this string str)
{
return str.Replace(" ", string.Empty);
}
最終的に、上記の 3 つの拡張機能をすべて組み合わせて使用しています。
public static string LatinizeAndConvertToASCII(this string str, bool keepSpace = false)
{
str = str.LatinizeGermanCharacters().ConvertWesternEuropeanToASCII();
return keepSpace ? str : str.RemoveSpace();
}
そして、成功する(網羅的ではない)小さな単体テスト。
[TestMethod()]
public void LatinizeAndConvertToASCIITest()
{
string europeanStr = "Bonjour ça va? C'est l'été! Ich möchte ä Ä á à â ê é è ë Ë É ï Ï î í ì ó ò ô ö Ö Ü ü ù ú û Û ý Ý ç Ç ñ Ñ";
string expected = "Bonjourcava?C'estl'ete!IchmoechteaeAeaaaeeeeEEiIiiiooooeOeUeueuuuUyYcCnN";
string actual = europeanStr.LatinizeAndConvertToASCII();
Assert.AreEqual(expected, actual);
}
これは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
これは、すべての.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
まだ検討していない場合は、このライブラリをここにポップします。それにはあらゆる種類の単体テストがあるようです。
HelperSharp パッケージを試してください。
メソッドRemoveAccentsがあります:
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;
}
Encoding.ASCII.GetString(Encoding.GetEncoding(1251).GetBytes(text));
実際には、 å
1 つの文字 (文字 code00E5
であり、同じように見える修飾子ではありません) をいくつか の修飾子に分割し、ASCII 変換で修飾子を削除して、 のみを残します。0061
030A
a
a
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
MMLib.Extensions nuget パッケージの文字列拡張機能を使用できます。
using MMLib.RapidPrototyping.Generators;
public void ExtensionsExample()
{
string target = "aácčeéií";
Assert.AreEqual("aacceeii", target.RemoveDiacritics());
}
Nuget ページ: https://www.nuget.org/packages/MMLib.Extensions/ Codeplex プロジェクト サイトhttps://mmlib.codeplex.com/