Próbuję przekonwertować niektóre ciągi znaków, które są w języku francuskim kanadyjskim i, w zasadzie, chciałbym być w stanie usunąć francuskie znaki akcentujące litery przy jednoczesnym zachowaniu litery. (Np. Przekonwertuj é
na e
, więc crème brûlée
się stanie creme brulee
)
Jaka jest najlepsza metoda na osiągnięcie tego?
.net
string
diacritics
James Hall
źródło
źródło
Odpowiedzi:
Nie użyłem tej metody, ale Michael Kaplan opisuje metodę jej wykonania w swoim blogu (z mylącym tytułem), która mówi o usuwaniu znaków diakrytycznych: Stripping to interesująca praca (aka W znaczeniu nieistotnych, czyli wszystkich znaków Mn są nierozstawne, ale niektóre są bardziej nierozstawne niż inne)
Zauważ, że jest to kontynuacja jego wcześniejszego postu: Usuwanie diakrytów ....
Podejście wykorzystuje String.Normalize, aby podzielić ciąg wejściowy na glify składowe (w zasadzie oddzielając znaki „bazowe” od znaków diakrytycznych), a następnie skanuje wynik i zachowuje tylko znaki podstawowe. To tylko trochę skomplikowane, ale tak naprawdę patrzysz na skomplikowany problem.
Oczywiście, jeśli ograniczasz się do francuskiego, prawdopodobnie możesz uciec od prostego podejścia opartego na tabeli w Jak usunąć akcenty i tyldę w std :: string C ++ , zgodnie z zaleceniem @David Dibben.
źródło
to załatwiło sprawę dla mnie ...
szybkie i krótkie!
źródło
«
»
i…
(jako jeden znak), zostanie zmienionych w procesie, co nie jest zgodne z przyjętym rozwiązaniem.System.ArgumentException: 'ISO-8859-8' is not a supported encoding name.
System.Text.Encoding.CodePages
z nuget, a następnie zadzwoń, aby zarejestrować dostawcę:Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
- gdy to zrobisz, możesz skorzystać z ISO-8859-8Gdyby ktoś był zainteresowany, szukałem czegoś podobnego i skończyłem pisać:
źródło
c < 128
, aby upewnić się, że nie pobieramy żadnych znaków UTF, zobacz tutaj .c < 123
. patrz ASCIPotrzebowałem czegoś, co konwertuje wszystkie główne znaki Unicode, a głosowana odpowiedź pozostawiła kilka, więc stworzyłem wersję CodeIgniter's
convert_accented_characters($str)
w języku C #, który można łatwo dostosować:Stosowanie
źródło
if (entry.Key.IndexOf(c) != -1)
naif (entry.Key.Contains(c))
{ "äæǽ", "ae" }
zamiast po{ "ä", "ae" }, { "æ", "ae" }, { "ǽ", "ae" }
prostu dzwonićif (foreign_characters.TryGetValue(...)) ...
. Całkowicie pokonałeś cel indeksu, który już ma słownik.Jeśli ktoś jest zainteresowany, oto odpowiednik java:
źródło
Często używam metody rozszerzenia opartej na innej wersji, którą znalazłem tutaj (zobacz Zastępowanie znaków w C # (ascii) ) Szybkie wyjaśnienie:
Kod:
źródło
CodePage Greek (ISO) może to zrobić
Informacje o tej stronie kodowej znajdują się w
System.Text.Encoding.GetEncodings()
. Dowiedz się więcej na: https://msdn.microsoft.com/pt-br/library/system.text.encodinginfo.getencoding(v=vs.110).aspxGrecki (ISO) ma stronę kodową 28597 i nazwę iso-8859-7 .
Idź do kodu ... \ o /
Napisz więc tę funkcję ...
Zauważ, że ...
Encoding.GetEncoding("iso-8859-7")
jest równoważne,Encoding.GetEncoding(28597)
ponieważ pierwszy to nazwa, a drugi strona kodowa Kodowania.źródło
äáčďěéíľľňôóřŕšťúůýž ÄÁČĎĚÉÍĽĽŇÔÓŘŔŠŤÚŮÝŽ ÖÜË łŁđĐ ţŢşŞçÇ øı
). Problemy znaleziono tylko w przypadkußə
, na które są konwertowane?
, ale takie wyjątki zawsze można rozwiązać osobno. Przed wprowadzeniem go do produkcji należy lepiej wykonać test na wszystkich obszarach Unicode zawierających litery ze znakami diakrytycznymi.To zabawne, że takie pytanie może uzyskać tak wiele odpowiedzi, a jednak żadne nie spełnia moich wymagań :) Jest tak wiele języków wokół, rozwiązanie agnostyczne w pełnym języku jest AFAIK, nie jest tak naprawdę możliwe, jak inni wspominali, że FormC lub FormD powodują problemy.
Ponieważ pierwotne pytanie dotyczyło języka francuskiego, odpowiedź jest najprostsza
1251 należy zastąpić kodowaniem języka wejściowego.
Zastępuje to jednak tylko jeden znak jednym znakiem. Ponieważ pracuję również z niemieckim jako danymi wejściowymi, dokonałem ręcznej konwersji
Może nie zapewniać najlepszej wydajności, ale przynajmniej jest bardzo łatwy do odczytania i rozszerzenia. Regex jest NO GO, znacznie wolniejszy niż jakikolwiek ciąg znaków / znaków.
Mam również bardzo prostą metodę usuwania miejsca:
W końcu używam kombinacji wszystkich 3 powyższych rozszerzeń:
I mały test jednostkowy do tego (nie wyczerpujący), który pomyślnie przeszedł.
źródło
Działa to dobrze w Javie.
Zasadniczo konwertuje wszystkie znaki akcentowane na ich odpowiedniki deAccented, a następnie łączą znaki diakrytyczne. Teraz możesz użyć wyrażenia regularnego, aby usunąć znaki diakrytyczne.
źródło
"\\p{Block=CombiningDiacriticalMarks}"
TL; DR - C # metoda przedłużenia łańcucha
Myślę, że najlepszym rozwiązaniem, aby zachować sens napisu jest konwersja znaków zamiast ich usuwania, co dobrze ilustruje przykład
crème brûlée
docrme brle
wersetachcreme brulee
.Sprawdziłem powyższy komentarz Aleksandra i zobaczyłem, że kod Lucene.Net ma licencję Apache 2.0, więc zmodyfikowałem klasę do prostej metody rozszerzenia łańcucha. Możesz użyć tego w następujący sposób:
Ta funkcja jest zbyt długa, aby opublikować ją w odpowiedzi StackOverflow (~ 139 tys. Znaków z 30 tys. Dozwolonych lol), więc sporządziłem listę i przypisałem autorom :
Mam nadzieję, że pomoże to komuś innemu. To najbardziej niezawodne rozwiązanie, jakie znalazłem!
źródło
TO JEST WERSJA VB (współpracuje z GRECKIM):
Importuje System.Text
Importuje system. Globalizacja
źródło
Wypróbuj pakiet HelperSharp .
Istnieje metoda RemoveAccents:
źródło
W ten sposób zamieniam znaki diakrytyczne na znaki niediakrytyczne w całym moim programie .NET
DO#:
VB .NET:
źródło
możesz użyć rozszerzenia ciągu z pakietu nuget MMLib.Extensions:
Strona Nuget: https://www.nuget.org/packages/MMLib.Extensions/ Strona projektu Codeplex https://mmlib.codeplex.com/
źródło
Umieszczanie tej biblioteki tutaj, jeśli jeszcze jej nie rozważałeś. Wygląda na to, że zawiera pełen zakres testów jednostkowych.
https://github.com/thomasgalliker/Diacritics.NET
źródło
źródło
Co ta osoba powiedziała:
Encoding.ASCII.GetString(Encoding.GetEncoding(1251).GetBytes(text));
W rzeczywistości dzieli takie, w
å
których jeden znak (który jest kodem znaków00E5
, a nie0061
modyfikator,030A
który wyglądałby tak samo) naa
plus jakiś modyfikator, a następnie konwersja ASCII usuwa modyfikator, pozostawiając jedynya
.źródło
Bardzo podoba mi się zwięzły i funkcjonalny kod dostarczony przez azrafe7 . Więc zmieniłem to trochę, aby przekonwertować na metodę rozszerzenia:
źródło
Nie mając wystarczającej reputacji, najwyraźniej nie mogę skomentować doskonałego linku Aleksandra. - Lucene wydaje się być jedynym rozwiązaniem działającym w uzasadnionych przypadkach ogólnych.
Dla tych, którzy chcą prostego rozwiązania kopiuj-wklej, oto kod wykorzystujący kod w Lucene:
testbed string = "ÁÂĘÅÇÇÍÍÎÓÖØÚÜÞàáâãäåæçèéêëìíîïðñóôöøúüāăčĐęğıŁłńŌōřŞşšźžșțệủ";
Console.WriteLine (Lucene.latinizeLucene (testbed));
//////////
źródło