2012-04-09 7 views
3

Für eine diakritische unabhängige Volltextsuche, verwende ich den folgenden Code akzentuierte Zeichen wie é oder Ö in ihre Klein nicht-akzentuierte Form e und oGibt es eine Möglichkeit, NSString stringByFoldingWithOptions zu verwenden, um das einzelne französische 'œ' Zeichen in 'oe' zu entfalten?

[[inputString stringByFoldingWithOptions: 
    NSCaseInsensitiveSearch 
    + NSDiacriticInsensitiveSearch 
    + NSWidthInsensitiveSearch 
locale: [NSLocale currentLocale]] lowercaseString]; 

Dies funktioniert zu konvertieren. Allerdings habe ich keine Möglichkeit gefunden, Sonderzeichen, deren Grundform aus mehreren Zeichen besteht, wie die französische œ (wie in "sœur") oder die deutsche ß (wie in 'Fluß') zu konvertieren. Ich möchte sie in oe bzw. ss konvertieren. Ich habe keine Markierung für stringByFoldingWithOptions gefunden und im Web nichts gefunden.

EDIT

ß tatsächlich korrekt durch den obigen Code behandelt. Es konvertiert zu ss.

+0

mögliches Duplikat von [NSString - wie man von "ÁlgeBra" zu "Algebra" geht] (http://stackoverflow.com/questions/5050270/nsstring-how-to-go-from-lgebra-to-algebra) – Jack

+0

Ich bin kein Experte, aber ich mache '-composedStringWithCompatibilityMapping' dies für Sie tun? – joerick

+0

- zersetzt sich leider nicht. :( – Wevah

Antwort

5

Von der schlechtesten zur besten Lösung.

Lösung 1 werden nur für æ und ß arbeiten und nicht für alles andere (œ, ij, ff, fi, fl, ffi, ffl, ft , st, ...):

NSString *result = [[[NSString alloc] initWithData:[inputString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES] encoding:NSASCIIStringEncoding] autorelease]; 

Lösung 2 funktioniert für die meisten Ligaturen und schlägt nur für æ, - und ij fehl. Ich habe versucht, alle möglich NSLocale, es ist also nicht das Problem hier:

NSString *result = [inputString stringByFoldingWithOptions:NSCaseInsensitiveSearch | NSDiacriticInsensitiveSearch | NSWidthInsensitiveSearch locale:[NSLocale currentLocale]]; 

Lösung 3 für die meisten Ligaturen arbeiten und nicht nur für œ:

NSString *result = [[[NSString alloc] initWithData:[[inputString precomposedStringWithCompatibilityMapping] dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES] encoding:NSASCIIStringEncoding] autorelease]; 

Was bedeutet œ wird muss immer manuell gehandhabt werden. Die beste Lösung besteht darin, entweder Lösung 2 oder 3 mit einem manuellen String-Ersatz zu kombinieren.

Lösung 2bis:

inputString = [inputString stringByReplacingOccurrencesOfString:@"æ" withString:@"ae" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [inputString length])]; 
inputString = [inputString stringByReplacingOccurrencesOfString:@"œ" withString:@"oe" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [inputString length])]; 
inputString = [inputString stringByReplacingOccurrencesOfString:@"ij" withString:@"ij" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [inputString length])]; 
NSString *result = [inputString stringByFoldingWithOptions:NSCaseInsensitiveSearch | NSDiacriticInsensitiveSearch | NSWidthInsensitiveSearch locale:[NSLocale currentLocale]]; 

Lösung 3bis:

inputString = [inputString stringByReplacingOccurrencesOfString:@"Œ" withString:@"OE"]; 
inputString = [inputString stringByReplacingOccurrencesOfString:@"œ" withString:@"oe"]; 
NSString *result = [[[NSString alloc] initWithData:[[inputString precomposedStringWithCompatibilityMapping] dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES] encoding:NSASCIIStringEncoding] autorelease]; 

Zu wissen, ich könnte einige Ersatz mit Lösung 2bis fehlt und NSLocale ist unberechenbar, beste Lösung 3bis ist. Und auch diese letzte Lösung ermöglicht es Ihnen, die Groß-/Kleinschreibung bei Bedarf zu berücksichtigen.

+2

Ich denke, der beste Teil dieser Lösung ist die Tatsache, dass der Benutzer, der es vorschlägt, den fraglichen Charakter in seinem Namen verwendet. – dpassage

+1

Ich denke, der beste Teil dieser Antwort ist, dass es tatsächlich eine Lösung darstellt! – regular

0

Werfen Sie einen Blick auf CFStringTransform() und seine kCFStringTransformToLatin Option. Ich denke, dass das tun kann, wonach Sie suchen.

+0

habe ich 'CFStringTransform (Zeichenfolge, NULL, kCFStringTransformToLatin, FALSE) versucht;' Es gibt 1 zurück, die Zeichenfolge bleibt jedoch unverändert ('sœur') – regular

+0

Das gleiche gilt für 'kCFStringTransformStripCombiningMarks' – regular