2015-11-05 10 views
10
string s = "Gewerbegebiet Waldstraße"; //other possible input "Waldstrasse" 

int iFoundStart = s.IndexOf("strasse", StringComparison.CurrentCulture); 
if (iFoundStart > -1) 
    s = s.Remove(iFoundStart, 7); 

Ich verwende CultureInfo 1031 (deutsch).ArgumentOutOfRangeException mit IndexOf mit CultureInfo 1031

IndexOf passt 'straße' oder 'strasse' mit definierter 'strasse' und gibt 18 als Position zurück.

Weder Entfernen noch Ersetzen haben eine Überladung zum Einstellen einer Kultur.

Wenn ich 6 Zeichen mit Entfernen lösche, wird 1 Zeichen übrig bleiben, wenn Eingabezeile 'Straße' und 'Straße' funktionieren. Wenn Eingabe-String ist 'Straße' und ich 7 Zeichen entfernen, bekomme ich ArgumentOutOfRangeException.

Gibt es eine Möglichkeit, die gefundene Zeichenfolge sicher zu entfernen? Jede Methode, die den letzten Index von IndexOf bietet? Ich trat näher in IndexOf und es ist nativen Code unter der Haube wie erwartet - also keine Möglichkeit, etwas eigenes zu tun ...

+0

Wie wäre es mit einem leeren String zu ersetzen? 's = s.Replace (" strasse "," ");' – dotctor

+0

@dotctor Ich glaube, das OP sagt, dass 'string.Replace' die Kultur nicht berücksichtigt, also passt" ss "nicht zu" ß ". – juharr

+0

Ich laufe auf 'en-US' und habe dieses Problem.die Sache ist IndexOf verhält sich anders. –

Antwort

5

Die native Win32-API legt die Länge der Zeichenfolge, die gefunden wurde. Sie können P/Invoke verwenden FindNLSStringEx direkt anrufen:

static class CompareInfoExtensions 
{ 
    [DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)] 
    private static extern int FindNLSStringEx(string lpLocaleName, uint dwFindNLSStringFlags, string lpStringSource, int cchSource, string lpStringValue, int cchValue, out int pcchFound, IntPtr lpVersionInformation, IntPtr lpReserved, int sortHandle); 

    const uint FIND_FROMSTART = 0x00400000; 

    public static int IndexOfEx(this CompareInfo compareInfo, string source, string value, int startIndex, int count, CompareOptions options, out int length) 
    { 
     // Argument validation omitted for brevity 
     return FindNLSStringEx(compareInfo.Name, FIND_FROMSTART, source, source.Length, value, value.Length, out length, IntPtr.Zero, IntPtr.Zero, 0); 
    } 
} 

static class Program 
{ 
    static void Main() 
    { 
     var s = "<<Gewerbegebiet Waldstraße>>"; 
     //var s = "<<Gewerbegebiet Waldstrasse>>"; 
     int length; 
     int start = new CultureInfo("de-DE").CompareInfo.IndexOfEx(s, "strasse", 0, s.Length, CompareOptions.None, out length); 
     Console.WriteLine(s.Substring(0, start) + s.Substring(start + length)); 
    } 
} 

Ich bin nicht eine Art und Weise zu sehen, diese rein die BCL mit zu tun.

+0

Wenn ich "Berliner Straße" anpassen und CompareOptions.IgnoreCase verwenden möchte, scheitert das - keine Ahnung warum? – isHuman

+0

@isHuman Ich habe die Konvertierung von 'CompareOptions' nach' FindNLSStringEx' weggelassen. Sie können sehen, dass der Parameter 'options' nicht verwendet wird. Sie müssen eine Konvertierung von 'CompareOptions.IgnoreCase' zu' LINGUISTIC_IGNORECASE' oder 'NORM_IGNORECASE' hinzufügen (die von Ihnen festgelegt werden). – hvd

+0

Yep sah das gleiche jetzt :) Will versuchen. – isHuman