Domanda

Sto cercando di scrivere una funzione di elaborazione di stringa in F #, che assomiglia a questo:

let rec Process html =
  match html with
  | '-' :: '-' :: '>' :: tail -> ("→" |> List.of_seq) @ Process tail
  | head :: tail -> head :: Process tail
  | [] -> []

Il mio modello di corrispondenza di espressione contro diversi elementi è un brutto (il tutto '-' :: '-' :: '>') bit. C'è un modo per renderlo migliore? Inoltre, è quello che sto facendo efficiente se dovessi elaborare grandi testi? O c'è un altro modo?

Chiarimento : quello che voglio dire è, per esempio, essere in grado di scrivere qualcosa del genere:

match html with
| "-->" :: tail -> 
È stato utile?

Soluzione

Sono d'accordo con gli altri che l'utilizzo di un elenco di caratteri per fare seria manipolazione di stringhe non è probabilmente l'ideale. Tuttavia, se si desidera continuare a utilizzare questo approccio, un modo per ottenere qualcosa di simile a quello che stai chiedendo è quello di definire un modello attivo. Per esempio:

let rec (|Prefix|_|) s l =
  if s = "" then
    Some(Prefix l)
  else
    match l with
    | c::(Prefix (s.Substring(1)) xs) when c = s.[0] -> Some(Prefix xs)
    | _ -> None

Quindi è possibile utilizzare le cose come:

let rec Process html =  
  match html with  
  | Prefix "-->" tail -> ("→" |> List.of_seq) @ Process tail  
  | head :: tail -> head :: Process tail  
  | [] -> []

Altri suggerimenti

  

C'è un modo per renderlo migliore?

Certo:

let process (s: string) = s.Replace("-->", "→")
  

Inoltre, è quello che sto facendo efficiente se dovessi elaborare grandi testi?

No, è incredibilmente inefficiente. Assegnazione e garbage collection è costoso e si sta facendo così per ogni singolo carattere.

  

O c'è un altro modo?

Prova il membro Replace. Se questo non funziona, provare un'espressione regolare. Se questo non funziona, scrivere un lexer (per esempio usando fslex). In definitiva, ciò che si vuole per l'efficienza è una macchina a stati l'elaborazione di un flusso di caratteri e di emettere il suo risultato mutando sul posto.

Penso che si dovrebbe evitare di utilizzare l'elenco e l'utilizzo di archi e per esempio String.Replace, String.Contains, ecc System.String e System.StringBuilder sarà molto meglio per manipolare il testo di lista .

Per problemi semplici, utilizzando String e StringBuilder direttamente come detto Brian è probabilmente il modo migliore. Per problemi più complessi, si consiglia di controllare alcuni sofisticata libreria di analisi come FParsec per F #.

Questa domanda può essere qualche aiutare a darvi idee per un altro modo di affrontare il problema -. utilizzando l'elenco <> per contenere le linee, ma utilizzando le funzioni di stringa all'interno di ogni riga

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top