查找并替换文本文件输出中的单词

问题描述:

我是haskell的新故障,我在尝试使此脚本正常工作时遇到了相当多的麻烦。其目的是让它从命令行中读取参数,并在单独的文本文件中找到它们。然后用与该词的长度相同量的星号代替这些词。我已经设法让它找到一个替代的话,但自此以后就已经碰壁了。我尝试了各种各样的方式,希望有人能够为我澄清它。查找并替换文本文件输出中的单词

module Main where 

import System 
import Data.Char 

lowercase = map toLower 


main = do (arg1:arg2:arg3:arg4:arg5:_) <- getArgs 
      txt <- getContents 
      putStr (redact txt arg1 arg2 arg3 arg4 arg5) 


redact file w1 w2 w3 w4 w5 = unlines [ process line | line <- lines file ] 
     where process line = unwords [ f word | word <- words line ] 
      f w | lowercase(w) == lowercase(w1) = convertWord w 1 
       | lowercase(w) == lowercase(w2) = convertWord w 1 
       | lowercase(w) == lowercase(w3) = convertWord w 1 
       | lowercase(w) == lowercase(w4) = convertWord w 1 
       | lowercase(w) == lowercase(w5) = convertWord w 1 
       | otherwise = w 

convertWord :: Eq a => [a] -> [a] -> [a] -> [a] 
convertWord [] _ = [] 

convertWord word count = temp 
     where if count == 1 then let temp = "" 
      if count <= length(word) 
         then temp = temp ++ "*" 
          convertWord word count+1 

的想法是,在convertWord部分称为并创建星号的字符串,以反馈至要被显示在输出中纂。然而,当我尝试编译此,GHC返回错误“redact.hs:28:13:解析错误(可能是不正确的缩进)”提前为任何帮助

感谢您能提供

汤姆

+3

一个提示,我强烈建议您尝试避免代码中的代码重复。考虑如何将所有“小写字母(w)==小写字母(w1)= convertWord w 1 '警卫转换为单个。永远不要复制代码是一个好习惯。 :) – Tarrasch 2011-03-20 22:31:59

+2

例如,你可以做这样的事情:'小写w \'elem \'映射小写[w1,w2,w3,w4,w5]' – fuz 2011-03-21 07:07:48

你想要一个函数,它需要一个字符串,说,"hello",并将它变为"*****"(都有长度5),是否正确?

只需使用map (const '*')(即函数:))。示例:map (const '*') "hello"收益率"*****"

还有另一种变体,其中输入参数必须是[Char],而不是[a]。用于map (asTypeOf '*')。但是,你可能不需要这个。

我真的不确定你想要什么。也许你可以澄清你的例子举例说明你希望你的函数做什么。

哦,你的编译错误是由于你用奇怪的方式使用了where语法。 :)

希望这有助于!

+0

这正是我在寻找的非常感谢! – espsquall 2011-03-20 22:15:08

+1

@espsquall [不是一个字。](http://hyperboleandahalf.blogspot。com/2010/04/alot-is-better-than-you-at-everything.html) – ephemient 2011-03-21 18:37:41

我尽量给大家介绍一下代码一些启示:

我看到的第一件事情,就是你解构参数列表,并将其送入redact。这不太好,因为你不能提供超过5个单词。如何使用列表作为参数并使用lowercase w \ elem` map小写wList`来检查条件?

另一件事是列表理解。如果你不想利用它的特殊功能,通常使用一个map来冗余。也适用塔拉什的提示,以你的代码,它可能是这样的:

module Main where 

import System 
import Data.Char 

lowercase :: String -> String 
lowercase = map toLower 

main :: IO() 
main = do args <- getArgs 
      txt <- getContents 
      putStr (redact txt args) 

redact :: String -> [String] -> String 
redact file wList = unlines . map process $ lines file 
     where process = unwords . map f . words 
      f w | lowercase w `elem` map lowercase wList = convertWord w 
       | otherwise        = w 

convertWord :: Eq a => [a] -> [a] 
convertWord :: map (const '*') 

在Haskell,你很快就能学会如何在地图和褶皱的长期思考。一旦你习惯了它们,你几乎只会使用库函数;显式递归很少需要。

+0

一个小问题是,你不需要convertqord的'Eq a =>'。 – Tarrasch 2011-03-21 20:48:25