2017-12-23 17 views
1

123_のような文字列から123 :: Integerの値を検索するには、正規表現関連のHaskellライブラリを使用しますか?正規表現を使って整数をHaskellにマッチさせるにはどうすればよいですか?

import Text.Regex.Posix 

let (_,_,_,[sectionKey]) = ("123_") =~ ("(\\d+)_" :: String) :: (String, String, String, [Int]) 

私はエラーを生成します(https://hackage.haskell.org/package/regex-posixライブラリを使用して)上記を試してみた:

• No instance for (RegexContext 
        Regex [Char] (String, String, String, [Int])) 
    arising from a use of ‘=~’ 
• In the expression: 
     ("123_") =~ ("(\\d+)_" :: String) :: 
     (String, String, String, [Int]) 
    In a pattern binding: 
    (_, _, _, [sectionKey]) 
     = ("123_") =~ ("(\\d+)_" :: String) :: 
      (String, String, String, [Int]) 

これは単純化された場合ですが、私は正規表現を提供するソリューションを探しています互換性のあるソリューションです。

+1

を、それを使用して、\ D + '。*'の代わりに '? – Jan

+0

提案をお寄せいただきありがとうございます。どちらも問題ありません。 –

+0

このエラーを解決するために何をしましたか?そのようなインスタンスは実際にはありませんので、もちろんこのコードは機能しません(インスタンスが実際に存在するような異なるタイプを指定してください)。 – user2407038

答えて

7

まず最初にRegexライブラリは使用しません。now you got two problemsのhaskellはいい仕事をしてくれます。パーサーの素晴らしいエコシステムはありません。

問題を解決するには、間違った正規表現を使用したと思います。しかも -

$ stack ghci --package regex-posix --package safe 
... 
Prelude> :m + Safe Text.Regex.Posix 
Prelude Safe Text.Regex.Posix> readMay ("123_" =~ "[0-9]+") :: Maybe Integer 
Just 123 

正規表現を使用しての欠点は、彼らが、/理解して最初の場所で権利を取得し、その後維持するのは難しい(私の意見では)エラーが生じやすいです。そしてあなたがそれにマッチすると、一致したStringが得られます。私。 ("123_" =~ "([0-9]+)_") :: Stringは "123_"で、 "123"ではないため、 "readMay ..."はJust 123の代わりにNothingを返します。

したがって、私はattoparsecのような構文解析ライブラリの使用をお勧めします。しかし、私が言ったように、あなたがこれを気に入らなければ、多くの構文解析の選択肢があります。 GHCiの中でこれを置く

$ stack ghci --package attoparsec 
Prelude> :set -XOverloadedStrings 
Prelude> import Data.Attoparsec.ByteString.Char8 as C8 
Prelude Data.Attoparsec.Char8> :{ 
Prelude Data.Attoparsec.Char8| strangeNumber = do 
Prelude Data.Attoparsec.Char8| d <- decimal 
Prelude Data.Attoparsec.Char8| char '_' 
Prelude Data.Attoparsec.Char8| return d 
Prelude Data.Attoparsec.Char8| :} 
Prelude C8> parseOnly strangeNumber "123_" :: Either String Integer 
Right 123 

少し扱いに​​くいですが、ファイルにそれは完全に罰金と保守性である - ので、あなたは番号の先頭および/または末尾に「_」オプションを可能にしたい場合は、あなたのことができ

StrangeNumber.hs

strangeNumber :: Parser Integer 
strangeNumber = do 
    skipMany (char '_') 
    d <- decimal 
    skipMany (char '_') 
    return d 

としてこれを書いて、なぜ `使用しないでGHCiの

Prelude Data.Attoparsec.ByteString.Char8> parseOnly strangeNumber "123_" 
Right 123 
Prelude Data.Attoparsec.ByteString.Char8> parseOnly strangeNumber "_123_" 
Right 123 
Prelude Data.Attoparsec.ByteString.Char8> parseOnly strangeNumber "_123__" 
Right 123 
関連する問題