2014-04-16 6 views
15
match (str) { 
    case "String1" => ??? 
    case "String2" => ??? 
} 

Dies ist die Groß- und Kleinschreibung. Wie schreibe ich Groß-und Kleinschreibung nicht? Ich weiß, dass ich für jeden Zweig zu PowerCase anrufen kann, aber ich möchte eine elegantere Lösung.Groß-/Kleinschreibung nicht passend für Strings

+1

Anruf toLowerCase auf 'str' diese Vervielfältigung wird vermieden (obviosly die alle Fall Optionen müssen dann Kleinbuchstaben sein). –

+0

Case-Optionen sind Konstanten, die ich nicht ändern kann – ZhekaKozlov

+0

@orionll und Sie können ganze Spielanweisung nicht umschreiben, richtig? (z. B. Ersetzen von einfachen Zeichenfolgen durch die Regexp-Matcher) –

Antwort

20

Grundansatz:

könnten Sie verwenden Muster Guards und Reguläre Ausdrücke

str match { 
case s if s matches "(?i)String1" => 1 
case s if s matches "(?i)String2" => 2 
case _ => 0 
} 

Hoch entwickelte Methode:

Implicits mit String Interpolation und Regex

implicit class CaseInsensitiveRegex(sc: StringContext) { 
    def ci = ("(?i)" + sc.parts.mkString).r 
} 

def doStringMatch(str: String) = str match { 
    case ci"String1" => 1 
    case ci"String2" => 2 
    case _ => 0 
} 

Einige Beispiel für die Verwendung in der REPL:

scala> doStringMatch("StRINg1") 
res5: Int = 1 

scala> doStringMatch("sTring2") 
res8: Int = 2 
+9

Es gibt eine Funktion 'String.equalsIgnoreCase'. Keine Notwendigkeit für reguläre Ausdrücke. – ZhekaKozlov

+0

Ha, wollte das nur vorschlagen. –

+0

Wie funktioniert es? Was ist 'map (_ =>" x ")'? – ZhekaKozlov

5

Ein weiterer Ansatz, der nicht auf reguläre Ausdrücke oder interpolaters abhängt:

implicit class StringExtensions(val s: String) extends AnyVal { 
    def insensitive = new { 
     def unapply(other: String) = s.equalsIgnoreCase(other) 
    } 
    } 

    val test1 = "Bye".insensitive 
    val test2 = "HELLo".insensitive 

    "Hello" match { 
    case test1() => println("bad!") 
    case test2() => println("sweet!") 
    case _ => println("fail!") 
    } 

Hier ist eine andere Weg mit Interpolatoren, aber keine Regex:

implicit class StringInterpolations(sc: StringContext) { 
    def ci = new { 
     def unapply(other: String) = sc.parts.mkString.equalsIgnoreCase(other) 
    } 
    } 

    "Hello" match { 
    case ci"Bye" => println("bad!") 
    case ci"HELLO" => println("sweet!") 
    case _ => println("fail!") 
    } 

Die oben kann auch auf Mustererkennung innerhalb Fallklassen, zB verwendet werden:

case class Dog(name: String) 

val fido = Dog("FIDO") 

fido match { 
    case Dog(ci"fido") => "woof"  
    case _ => "meow :("  
} 
+0

Das funktioniert nicht, aber wenn so etwas funktioniert, wäre das echt cool! Wenn Sie es zum Laufen bringen können, könnten Sie bitte näher darauf eingehen? – 0fnt

+1

@ user247077: Sorry, ich schrieb direkt in die Antwortbox und machte einen Tippfehler. Versuche es jetzt - ich habe es selbst verifiziert. – pathikrit

+1

Für diejenigen, die sich wundern, wie ich war, stützen sich beide Beispiele auf die Syntax von unapply, wobei der Rückgabewert ein boolescher Wert ist (die anderen zwei sind, wo der Rückgabewert ein 'Opt [T]' ist, oder ein 'Opt [Seq [ T]] '. Die zweite Beispiel-Syntax kann von s" xyz $ a "Art der Syntax vertraut sein. – 0fnt

2

Einfache Lösung:

val str = "string1" 

str toUpperCase match (str) { 
    case "STRING1" => ??? 
    case "STRING2" => ??? 
} 
+0

Scheint viel einfacher als andere Ansätze. Irgendwelche Nachteile, die ich nicht bemerke? – Metropolis

+0

Ein möglicher Nachteil ist, dass Sie möglicherweise Probleme haben mit Case-Konvertierung, wenn Sie nicht auf Locale achten.Zum Beispiel könnte ich abhängig von der Gebietsschemaeinstellung in I oder © umgewandelt werden. – yerlilbilgin