2015-11-05 11 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); 

Sono in esecuzione CultureInfo 1031 (tedesco).ArgumentOutOfRangeException using IndexOf con CultureInfo 1031

IndexOf corrisponde a "straße" o "strasse" con "strasse" definito e restituisce 18 come posizione.

Né Rimuovi né Sostituisci ha alcun sovraccarico per l'impostazione di una coltura.

Se rimuovo 6 caratteri utilizzando Rimuovi 1 carattere sarà lasciato se input-string è 'strasse' e 'straße' funzionerà. Se input-string è 'straße' e rimuovo 7 caratteri ottengo ArgumentOutOfRangeException.

C'è un modo per rimuovere in modo sicuro la stringa trovata? Qualche metodo che fornisce l'ultimo indice di IndexOf? Mi sono avvicinato a IndexOf ed è il codice nativo sotto il cofano come previsto - quindi non c'è modo di fare qualcosa di proprio ...

+0

Come sostituire con una stringa vuota? 's = s.Replace (" strasse "," ");' – dotctor

+0

@dotctor Credo che l'OP stia dicendo che 'string.Replace' non tiene conto della cultura, quindi" ss "non corrisponde" ß ". – juharr

+0

Im in esecuzione su 'en-US' e ha ottenuto questo problema. La cosa è che IndexOf si comporta diversamente. –

risposta

5

L'API Win32 nativa espone la lunghezza della stringa che è stata trovata. È possibile utilizzare P/Invoke per chiamare direttamente FindNLSStringEx:

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)); 
    } 
} 

io non sto vedendo un modo per farlo utilizzando esclusivamente il BCL.

+0

Se voglio abbinare "Berliner Straße" e usare CompareOptions.IgnoreCase, questo non funziona, per quale motivo? – isHuman

+0

@isHuman Ho omesso la conversione da 'CompareOptions' a' FindNLSStringEx' valori di opzione: puoi vedere che il parametro 'options' non viene utilizzato. Dovrai aggiungere una conversione da 'CompareOptions.IgnoreCase' a' LINGUISTIC_IGNORECASE' o 'NORM_IGNORECASE' (a tua discrezione). – hvd

+0

Yep ha visto lo stesso adesso :) Ci proverò. – isHuman