Haskell에서 정규식 패턴을 어떻게 명시합니까?
Nov 28 2020
다음 코드로 정규식 교체를 시도하고 있습니다.
import Text.RE.Replace
import Text.RE.TDFA.String
onlyLetters :: String -> String
onlyLetters s = replaceAll "" $ s *=~ [re|$([^a-zA-Z])|]
나는 이것에 대한 이해 가능한 문서를 찾는 것이 정말 어려웠다. 이로 인해 컴파일 오류가 발생합니다.
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
그 브래킷의 문제점은 무엇이며 어떻게 올바르게 수행 할 수 있습니까? 감사합니다 -Skye
답변
3 WillemVanOnsem Nov 28 2020 at 18:56
는 […|…|]
인 준 인용 구문 [하스켈-위키] . 이것은 Haskell 구문의 확장이며 기본적으로 활성화되어 있지 않습니다.
LANGUAGE
pragma 를 사용하여이 기능을 켤 수 있습니다 .
{-# LANGUAGE QuasiQuotes #-}
import Text.RE.Replace
import Text.RE.TDFA.String
onlyLetters :: String -> String
onlyLetters s = replaceAll "" $ s *=~ [re|$([^a-zA-Z])|]
유사 인용 부호는 Haskell 코드를 생성하고 이것은 Haskell 프로그램에서 사용됩니다. 즉, 준 따옴표를 통해 정규식의 유효성 검사를 컴파일 타임에 수행 할 수 있으며 런타임에 정규식을 컴파일하는 것과 비교하여 효율성을 약간 최적화 할 수도 있습니다.
주어진 onlyLetters
함수에 대해 다음을 얻습니다.
*Main> onlyLetters "fo0b4r"
"fobr"
2 JamesBrock Nov 29 2020 at 21:02
Willem Van Onsem의 답변이이 질문에 대한 더 나은 답변이지만 "대신이 문제를 시도해보십시오"라는 답변 을 제안하겠습니다 .
이것은 유사 인용 정규식의 복잡함없이 일반 Haskell에서 텍스트 대체를 수행 할 수있는 방법입니다.
와 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"