[VB.NET] accenten op letters verwijderen uit string

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • SLeddert
  • Registratie: December 2002
  • Laatst online: 24-06 08:03
Ik ben een applicatie aan het schrijven die de volledige namen van ons personeel vergelijkt met een string.
Nu hebben we een flink aantal namen met trema's, accents, etc. ( ë é , etc, etc.)

Zoals je begrijpt krijg ik geen positieve respons als ik de naam ' jose ' vergelijk met ' josé '.
Ik wil dus eigenlijk de speciale leestekens uit de string vervangen met de 'gewone' karaters.

Dus voordat ik begin met mijn vergelijking moet josé worden gewijzigd in jose.

Is hier in vb.net een handige manier voor ?

Karsten


Acties:
  • 0 Henk 'm!

  • NickThissen
  • Registratie: November 2007
  • Laatst online: 25-05 11:39
Ik denk dat je wel gewoon kunt replacen:
Visual Basic:
1
2
Dim name As String = "José Nuñez" ' ofzo :p
name = name.Replace("é", "e").Replace("ñ", "n")


Of er een handigere manier is weet ik niet. Lijkt me sterk.

Mijn iRacing profiel


Acties:
  • 0 Henk 'm!

  • CodeIT
  • Registratie: Juni 2002
  • Laatst online: 23:41

CodeIT

Code IT

Je zou eens naar de volgende code kunnen kijken: http://weblogs.asp.net/fm...accents-from-strings.aspx
Hier de VB.NET versie:
Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Imports System.Text
Imports System.Globalization

''' <summary>
''' Removes the special attributes of the letters passed in the word
''' </summary>
''' <param name="word">Word to be normalized</param>
Function RemoveDiacritics(ByRef word As String) As String
    Dim normalizedString As String = word.Normalize(NormalizationForm.FormD)
    Dim r As StringBuilder = New StringBuilder()
    Dim i As Integer
    Dim c As Char

    For i = 0 To i < normalizedString.Length
        c = normalizedString(i)
        If (CharUnicodeInfo.GetUnicodeCategory(c) <> UnicodeCategory.NonSpacingMark) Then
            r.Append(c)
        End If
    Next

    RemoveDiacritics = r.ToString
End Function

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Of je maakt gebruik van de Win32 API functie CompareStringEx. Even vlug (in C#) geflanst:

*Hier stond onzin. Zie hier*

[ Voor 127% gewijzigd door RobIII op 26-05-2010 14:01 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • apokalypse
  • Registratie: Augustus 2004
  • Laatst online: 25-06 12:06
Hoor je dit niet te doen met een string.Compare met een bepaalde Culture(info)?
The comparison uses the culture parameter to obtain culture-specific information such as casing rules and the alphabetic order of individual characters. For example, a culture could specify that certain combinations of characters be treated as a single character, or uppercase and lowercase characters be compared in a particular way, or that the sorting order of a character depends on the characters that precede or follow it.
Welke Culture of hoe je die precies opzet weet ik niet. Ik weet wel dat bovenstaande oplossingen niet mijn voorkeur hebben.

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
apokalypse schreef op woensdag 26 mei 2010 @ 13:43:
Welke Culture of hoe je die precies opzet weet ik niet. Ik weet wel dat bovenstaande oplossingen niet mijn voorkeur hebben.
Bij mijn weten is er geen mogelijkheid om diacritics te negeren. En dan kun je wel moeilijk gaan lopen replacen e.d. maar dan stamp ik toch liever even de Win32 API aan.

[edit]
My bad; het kan wél
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using System;
using System.Globalization;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            CultureInfo NL = new CultureInfo(1043);
            Console.WriteLine(NL.CompareInfo.Compare("Jose", "José", CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreSymbols));
            Console.WriteLine(NL.CompareInfo.Compare("Jose", "Josë", CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreSymbols));
            Console.WriteLine(NL.CompareInfo.Compare("Jose", "Josï", CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreSymbols));
            Console.WriteLine(NL.CompareInfo.Compare("Jose", "josé", CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreSymbols));
            Console.ReadKey();
        }
    }
}

0
0
-1
0

Zie documentatie

[ Voor 61% gewijzigd door RobIII op 26-05-2010 14:00 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • CodeIT
  • Registratie: Juni 2002
  • Laatst online: 23:41

CodeIT

Code IT

RobIII schreef op woensdag 26 mei 2010 @ 12:50:
Of je maakt gebruik van de Win32 API functie CompareStringEx.
Pas daarbij wel op dat het alleen vanaf Vista en later werkt.

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
CodeIT schreef op woensdag 26 mei 2010 @ 13:58:
[...]

Pas daarbij wel op dat het alleen vanaf Vista en later werkt.
Los van 't feit dat ik er al op teruggekomen ben ( :P ); er is ook nog CompareString welke vanaf W2k en hoger werkt.

[ Voor 10% gewijzigd door RobIII op 26-05-2010 14:12 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • SLeddert
  • Registratie: December 2002
  • Laatst online: 24-06 08:03
Jongens, bedankt voor de hulp !

Ik heb de code van CodeIT geprobeerd en deze werkt. :*)
Wel moet de regel For i = 0 To i < normalizedString.Length gewijzigd worden in For i = 0 To NormalizedString.Length -1

En als ik het zo lees,dan zou comparestringex (thx RobIII) ook moeten werken.

Karsten


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
*Hier stond wéér onzin. Heb m'n dag wel vandaag :X :P *
SLeddert schreef op woensdag 26 mei 2010 @ 14:21:
En als ik het zo lees,dan zou comparestringex (thx RobIII) ook moeten werken.
Ja, maar dat kan nog makkelijker zoals ik al zei: RobIII in "\[VB.NET] accenten op letters verwijderen..."
De code in VB.Net is echt niet heel verschillend hiervoor t.o.v. C# maar ik heb geen zin die voor je uit te schrijven.

[ Voor 48% gewijzigd door RobIII op 26-05-2010 14:32 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • CodeIT
  • Registratie: Juni 2002
  • Laatst online: 23:41

CodeIT

Code IT

SLeddert schreef op woensdag 26 mei 2010 @ 14:21:
Jongens, bedankt voor de hulp !

Ik heb de code van CodeIT geprobeerd en deze werkt. :*)
Wel moet de regel For i = 0 To i < normalizedString.Length gewijzigd worden in For i = 0 To NormalizedString.Length -1

En als ik het zo lees,dan zou comparestringex (thx RobIII) ook moeten werken.
Hij werkt inderdaad, maar ik zou zelf de door Roblll uitgeschreven code gebruiken. Deze is een stuk korter en maakt waarschijnlijk geen extra kopie van de string.

Acties:
  • 0 Henk 'm!

  • apokalypse
  • Registratie: Augustus 2004
  • Laatst online: 25-06 12:06
CodeIT schreef op woensdag 26 mei 2010 @ 14:37:
[...]

Hij werkt inderdaad, maar ik zou zelf de door Roblll uitgeschreven code gebruiken. Deze is een stuk korter en maakt waarschijnlijk geen extra kopie van de string.
Ik zou inderdaad ook de .Net libaries gebruiken. Hier in VB.net

Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Imports System
Imports System.Globalization

Namespace ConsoleApplication2
    Class Program
        Private Shared Sub Main(ByVal args As String())
            Dim NL As New CultureInfo(1043)
            Console.WriteLine(NL.CompareInfo.Compare("Jose", "José", CompareOptions.IgnoreCase Or CompareOptions.IgnoreNonSpace Or CompareOptions.IgnoreSymbols))
            Console.WriteLine(NL.CompareInfo.Compare("Jose", "Josë", CompareOptions.IgnoreCase Or CompareOptions.IgnoreNonSpace Or CompareOptions.IgnoreSymbols))
            Console.WriteLine(NL.CompareInfo.Compare("Jose", "Josï", CompareOptions.IgnoreCase Or CompareOptions.IgnoreNonSpace Or CompareOptions.IgnoreSymbols))
            Console.WriteLine(NL.CompareInfo.Compare("Jose", "josé", CompareOptions.IgnoreCase Or CompareOptions.IgnoreNonSpace Or CompareOptions.IgnoreSymbols))
            Console.ReadKey()
        End Sub
    End Class
End Namespace


thx http://www.developerfusion.com/tools/convert/csharp-to-vb/ :)

jammer dat string.Equals niet deze compareOptions heeft. Semantisch toch iets mooier.

[ Voor 3% gewijzigd door apokalypse op 26-05-2010 15:13 ]


Acties:
  • 0 Henk 'm!

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 18-06 11:36
Toch blijft het merkwaardig dat je "CompareOptions.IgnoreCase Or CompareOptions.IgnoreNonSpace" codet als je bedoelt "ignore case en ignore non-space".

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Acties:
  • 0 Henk 'm!

  • Ricvdp
  • Registratie: Juni 2005
  • Laatst online: 23-06 16:06
MSalters schreef op donderdag 27 mei 2010 @ 12:29:
Toch blijft het merkwaardig dat je "CompareOptions.IgnoreCase Or CompareOptions.IgnoreNonSpace" codet als je bedoelt "ignore case en ignore non-space".
Bitwise, geen logische OR..

Acties:
  • 0 Henk 'm!

  • apokalypse
  • Registratie: Augustus 2004
  • Laatst online: 25-06 12:06
Ricvdp schreef op donderdag 27 mei 2010 @ 12:32:
[...]

Bitwise, geen logische OR..
Inderdaad. Nog verwarrender:
C#:
1
2
//controleren of IgnoreCase is opgegeven. compareOptions is van type CompareOptions
bool ignoreCase = (compareOptions & CompareOptions.IgnoreCase) == CompareOptions.IgnoreCase;

Daarom heeft .Net 4 ook een Enum.HasFlag ;)

[ Voor 0% gewijzigd door apokalypse op 31-05-2010 14:04 . Reden: wel bitwise and gebruiken :) ]


Acties:
  • 0 Henk 'm!

  • GrimaceODespair
  • Registratie: December 2002
  • Laatst online: 26-06 15:00

GrimaceODespair

eens een tettenman, altijd ...

Ik heb een keer deze motherfucker gemaakt voor een url rewrite-gebeuren:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static string NormalizeForSEO(string text)
{
  // Fix possible unicode characters
  text = text.Normalize();

  // Replace all non-alphanumeric characters with a hyphen
  text = Regex.Replace(text, @"\W", "-");

  // Split up all diacritics into two characters (one alphanumeric, one diacritical)
  text = text.Normalize(System.Text.NormalizationForm.FormD);

  // Remove the diacritical characters
  text = Regex.Replace(text, @"(?!-)\W", "");

  // Return the normalized text
  return text;
}

Dat ging grotendeels goed, maar bijvoorbeeld "eszet" (ringel-s) werd niet vervangen, en deed ik via een normale replace. Er zullen vast nog wel gevallen zijn waar verkeerd gaat, maar tot nu toe heeft de code goed gediend.

Disclaimer: nee, performance en efficiëntie waren geen prioriteit ;)

[ Voor 4% gewijzigd door GrimaceODespair op 27-05-2010 14:32 ]

Wij onderbreken deze thread voor reclame:
http://kalders.be


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 26-06 13:46

.oisyn

Moderator Devschuur®

Demotivational Speaker

apokalypse schreef op donderdag 27 mei 2010 @ 13:00:
[...]

Inderdaad. Nog verwarrender:
C#:
1
2
//controleren of IgnoreCase is opgegeven. compareOptions is van type CompareOptions
bool ignoreCase = (compareOptions && CompareOptions.IgnoreCase) == CompareOptions.IgnoreCase;
Wat er verwarrend aan is is dat het fout is ;). Maar idd, in deze situaties mis ik de standaard !=0 check zoals in C en C++. Dan kun je gewoon schrijven:
C++:
1
2
3
4
if (compareOptions & CompareOptions.IgnoreCase)
{
    // ...
}

[ Voor 24% gewijzigd door .oisyn op 27-05-2010 14:46 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • apokalypse
  • Registratie: Augustus 2004
  • Laatst online: 25-06 12:06
.oisyn schreef op donderdag 27 mei 2010 @ 14:45:
[...]

Wat er verwarrend aan is is dat het fout is ;).
En in plaats dat je vermeld waar de fout zit >:) (&& moet & zijn)
Maar idd, in deze situaties mis ik de standaard !=0 check zoals in C en C++. Dan kun je gewoon schrijven:
C++:
1
2
3
4
if (compareOptions & CompareOptions.IgnoreCase)
{
    // ...
}
Dit is geen check. Dit heeft er mee te maken dat C# een strong type system heeft, en C een weak. Een if verwacht gewoon een boolean als condtie, en niet een of ander type. Persoonlijk vind ik de C manier ranzig, kan je net zo goed gaan scripten als je dat mooi vindt. :+
Pagina: 1