2015-07-11 114 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