2010-09-15 10 views
49

Estoy tratando de hacer coincidir el comienzo de las cadenas en f #. No estoy seguro si tengo que tratarlos como una lista de personajes o qué. Cualquier sugerencia sera apreciada.Coincidencia de patrones al comienzo de una cadena en f #

Aquí es una versión pseudo código de lo que estoy tratando de hacer

let text = "The brown fox.." 

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

Por lo tanto, quiero ir al inicio de la cadena y combinar. Tenga en cuenta que no estoy haciendo coincidir en una lista de cadenas, simplemente escribí lo anterior como una idea de la esencia de lo que estoy tratando de hacer.

Respuesta

84

Parametrizado active patterns al rescate!

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 buen ejemplo de patrones activos para nosotros que queremos aprender también! –

+1

Esta respuesta tiene una hermosa aplicación de composiciones de patrones activos para la coincidencia de cadenas: http://stackoverflow.com/questions/3686199/f-pattern-composition/3686555#3686555 –

+0

Esta respuesta es fantástica, pero debo admitir que estoy desconcertado . ¿De dónde viene el valor de "descanso" en la expresión del partido? –

12

Sí, tiene que tratarlos como una lista de caracteres si desea usar una expresión de coincidencia.

se limita a transformar la cadena con:

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

A continuación, se puede utilizar una expresión de coincidencia, sino que tendrá que utilizar caracteres (el tipo de elementos en la lista) para cada letra:

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

Como Brian sugiere Patrones Activos Paramétricos son mucho más agradables, hay algunos patrones útiles here (vaya al final de la página).

+0

Aunque yo prefiero la respuesta de Brian usando patrones activos, me pregunto si éste podría ser más eficiente si los posibles prefijos son sólo unos pocos y No largo. Alguna idea sobre esto? –

+0

Tiene que crear una matriz temporal y una lista F #, por lo que posiblemente muchos objetos que agreguen presión al GC. Esto no es óptimo en absoluto. Será mejor que uses dos 'StartsWith' o' StartsWith' + AP. – Stringer

+3

Dado que las cadenas ya son un 'char seq', podrías usar' Seq.toList'. – YotaXP

11

También es posible usar un guardia en el patrón:

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

Esto también fue un buen ejemplo, especialmente si desea hacer coincidir parcialmente un conmutador que contiene an = y un parámetro. – octopusgrabbus

Cuestiones relacionadas