2010-09-15 7 views
49

Sto cercando di far corrispondere l'inizio delle stringhe in f #. Non sono sicuro se devo trattarli come una lista di personaggi o cosa. Tutti i suggerimenti sarebbero apprezzati.Corrispondenza del motivo all'inizio di una stringa in f #

Ecco una versione di codice pseudo di quello che sto cercando di fare

let text = "The brown fox.." 

match text with 
| "The"::_ -> true 
| "If"::_ -> true 
| _ -> false 

Quindi, voglio guardare all'inizio della stringa e partita. Nota che non sto facendo corrispondenze su un elenco di stringhe ho appena scritto quanto sopra come un'idea dell'essenza di ciò che sto cercando di fare.

risposta

84

Parametrato active patterns per il salvataggio!

let (|Prefix|_|) (p:string) (s:string) = 
    if s.StartsWith(p) then 
     Some(s.Substring(p.Length)) 
    else 
     None 

match "Hello world" with 
| Prefix "The" rest -> printfn "Started with 'The', rest is %s" rest 
| Prefix "Hello" rest -> printfn "Started with 'Hello', rest is %s" rest 
| _ -> printfn "neither" 
+0

+1. Un bell'esempio di modelli attivi per noi che vogliamo anche imparare! –

+1

Questa risposta ha una bella applicazione di composizioni pattern attivi per la corrispondenza delle stringhe: http://stackoverflow.com/questions/3686199/f-pattern-composition/3686555#3686555 –

+0

Questa risposta è fantastica, ma devo ammettere che sono sconcertato . Da dove viene il valore "resto" nell'espressione della corrispondenza? –

12

Sì, è necessario trattarli come un elenco di caratteri se si desidera utilizzare un'espressione di corrispondenza.

trasforma semplicemente la stringa con:

let text = "The brown fox.." |> Seq.toList 

quindi è possibile utilizzare un'espressione partita, ma si dovrà utilizzare caratteri (il tipo di elementi nella lista) per ogni lettera:

match text with 
| 'T'::'h'::'e'::_ -> true 
| 'I'::'f'::_ -> true 
| _ -> false 

Come Brian suggerisce che i pattern attivi parametrizzati sono molto più belli, ci sono alcuni modelli utili here (vai alla fine della pagina).

+0

Mentre io preferisco la risposta di Brian usando i modelli attivi, mi chiedo se questo potrebbe essere più efficiente se le possibili prefissi sono solo alcuni e non molto tempo Qualche idea su questo? –

+0

Devi creare un array temporaneo e un elenco F #, quindi probabilmente molti oggetti che aggiungerebbero pressione sul GC. Questo non è affatto ottimale. Faresti meglio a usare due '' StartsWith' o 'StartsWith' + AP. – Stringer

+3

Poiché le stringhe sono già un 'char seq', puoi semplicemente usare' Seq.toList'. – YotaXP

11

Si potrebbe anche usare una guardia sul modello:

match text with 
| txt when txt.StartsWith("The") -> true 
| txt when txt.StartsWith("If") -> true 
| _ -> false 
+0

Anche questo è stato un buon esempio, soprattutto se si desidera corrispondere parzialmente su uno switch contenente un parametro = e un parametro. – octopusgrabbus

Problemi correlati