2015-07-11 116 views
4

我想從文件中解析Float值,使用逗號作爲小數點分隔符存儲它們。因此,我需要一個功能myParse :: String -> Float,例如,myParse "23,46" == 23.46如何用逗號代替小數點解析浮點數?

我對如何做到這一點的一些想法,但他們似乎都過於複雜,例如:

有沒有更簡單的方法,還是我真的需要使用解析庫?在第二種情況下,您能否請貼一些建議以便讓我開始?單形態限制讓我感到害怕,我相信在不使用語言擴展的情況下,必須有一種方法可以做到這一點。

回答

6

通過.代替,然後致電read足夠簡單;你只需要記住使用自己的專用的功能,而不是普通的老read

​​

在GHCI:

λ> readFloatWithComma "23,46" 
23.46 

關於parsec方法,儘管什麼the article you link to suggest中,單態限制需求不要擔心,只要您爲所有頂級綁定輸入簽名即可。特別是,下面的代碼不需要任何語言擴展到正確編譯(至少在GHC 7.10.1):

import Text.Parsec 
import Text.Parsec.String   (Parser) 
import Control.Applicative hiding ((<|>)) 

infixr 5 <++> 
(<++>) :: Applicative f => f [a] -> f [a] -> f [a] 
a <++> b = (++) <$> a <*> b 

infixr 5 <:> 
(<:>) :: Applicative f => f a -> f [a] -> f [a] 
a <:> b = (:) <$> a <*> b 

number :: Parser String 
number = many1 digit 

plus :: Parser String 
plus = char '+' *> number 

minus :: Parser String 
minus = char '-' <:> number 

integer :: Parser String 
integer = plus <|> minus <|> number 

float :: Parser Float 
float = fmap rd $ integer <++> decimal <++> exponent 
    where rd  = read :: String -> Float 
      decimal = option "" $ ('.' <$ char ',') <:> number 
      exponent = option "" $ oneOf "eE" <:> integer 

在GHCI:

λ> parseTest float "23,46" 
23.46 
-1

這個函數將返回正確的浮動無論小數點分隔符是逗號還是全角字符。 即使您使用空格或貨幣符號解析數字,它也能正常工作。 So: 1,2 => 1.2; 1 234.56 => 1234.56; 1,234,56 $ => 1234.56 我做了這個形式我的應用程序,也許它需要一些試井或改善...

function unformatNumber(value){ 
//remove symbols, spaces etc.. 
fvalue = value.replace(/[^0-9-,-.]/g, ''); 
//replace all non full stop characters with full stop 
ffvalue=fvalue.replace(/[^0-9-.]/g,'.'); 
//remove all but last full stop 
var last= ffvalue.lastIndexOf('.'); 
var butLast = ffvalue.substring(0,last).replace(/[^0-9]/g, ''); 
var res = butLast+ffvalue.substring(last); 
//parse float 
floatValue= parseFloat(res); 
return floatValue; 

}

+1

HMH,這個功能是JS,但也許可以作爲有用的想法或版主可以刪除它... – wino