Comment énoncez-vous un modèle regex dans Haskell?
J'essaye de faire une regex remplacer par le code suivant
import Text.RE.Replace
import Text.RE.TDFA.String
onlyLetters :: String -> String
onlyLetters s = replaceAll "" $ s *=~ [re|$([^a-zA-Z])|]
J'ai trouvé très difficile de trouver une documentation compréhensible à ce sujet. Cela produit l'erreur de compilation:
src\Pangram.hs:6:53: error: parse error on input `]'
|
6 | onlyLetters s = replaceAll "" $ (s *=~ [re|[a-zA-Z]|]) | ^ Progress 1/2 -- While building package pangram-2.0.0.12 (scroll up to its section to see the error) using: C:\sr\setup-exe-cache\x86_64-windows\Cabal-simple_Z6RU0evB_3.0.1.0_ghc-8.8.4.exe --builddir=.stack-work\dist\29cc6475 build lib:pangram test:test --ghc-options " -fdiagnostics-color=always" Process exited with code: ExitFailure 1 PS C:\Users\mcleg\Exercism\haskell\pangram> stack test pangram> configure (lib + test) Configuring pangram-2.0.0.12... pangram> build (lib + test) Preprocessing library for pangram-2.0.0.12.. Building library for pangram-2.0.0.12.. [1 of 2] Compiling Pangram src\Pangram.hs:7:56: error: parse error on input `]' | 7 | onlyLetters s = replaceAll "" $ s *=~ [re|$([^a-zA-Z])|]
| ^
Progress 1/2
-- While building package pangram-2.0.0.12 (scroll up to its section to see the error) using:
C:\sr\setup-exe-cache\x86_64-windows\Cabal-simple_Z6RU0evB_3.0.1.0_ghc-8.8.4.exe --builddir=.stack-work\dist\29cc6475 build lib:pangram test:test --ghc-options " -fdiagnostics-color=always"
Process exited with code: ExitFailure 1
Quel est le problème avec ce support et comment puis-je le faire correctement? Merci -Skye
Réponses
La syntaxe[…|…|]
est quasi-citation [haskell-wiki] . Il s'agit d'une extension de la syntaxe de Haskell et non activée par défaut.
Vous pouvez l'activer avec un LANGUAGE
pragma:
{-# LANGUAGE QuasiQuotes #-}
import Text.RE.Replace
import Text.RE.TDFA.String
onlyLetters :: String -> String
onlyLetters s = replaceAll "" $ s *=~ [re|$([^a-zA-Z])|]
Les quasiquotes généreront du code Haskell et celui-ci sera ensuite utilisé dans le programme Haskell. Cela signifie qu'à travers les quasiquotes, la validation de l'expression régulière peut être effectuée au moment de la compilation et pourrait même légèrement optimiser l'efficacité par rapport à la compilation de l'expression régulière au moment de l'exécution.
Pour la onlyLetters
fonction donnée , on obtient alors:
*Main> onlyLetters "fo0b4r"
"fobr"
La réponse de Willem Van Onsem est une meilleure réponse à la question, mais je vais suggérer une réponse «essayez ceci à la place» .
C'est ainsi que vous pouvez effectuer un remplacement de texte en Haskell simple sans la complication des expressions régulières quasi-citées.
Avec https://hackage.haskell.org/package/replace-megaparsec/docs/Replace-Megaparsec.html#v:streamEdit
{-# LANGUAGE TypeFamilies #-}
import Text.Megaparsec
import Text.Megaparsec.Char
import Replace.Megaparsec
import Data.Void
-- | Invert a single-token parser “character class”.
-- | For example, match any single token except a letter or whitespace: `anySingleExcept (letterChar <|> spaceChar)`
anySingleExcept :: (MonadParsec e s m, Token s ~ Char) => m (Token s) -> m (Token s)
anySingleExcept p = notFollowedBy p *> anySingle
-- | A parser monad pattern which matches anything except letters.
nonLetters :: Parsec Void String String
nonLetters = many (anySingleExcept letterChar)
onlyLetters :: String -> String
onlyLetters = streamEdit nonLetters (const "")
onlyLetters "fo0b4r"
"fobr"