【问题标题】:Haskell extract substring within a stringHaskell 提取字符串中的子字符串
【发布时间】:2014-02-13 09:45:08
【问题描述】:

我的目标是找出子字符串在字符串中存在的次数。 我要查找的子字符串类型为“[n]”,其中 n 可以是任何变量。

我的尝试涉及使用 words 函数拆分字符串, 如果字符串的“头”是“[”,则创建一个新的字符串列表 同一字符串的“最后一个”是“]”

我遇到的问题是我输入了一个字符串,当使用它进行拆分时 功能词,创建了一个看起来像这样“[2]”的字符串 现在,我仍然希望这算作“[n]”类型的出现

一个例子是我想要这个字符串,

asdf[1]jkl[2]asdf[1]jkl

返回 3。

这是我的代码:

-- String that will be tested on references function
txt :: String
txt = "[1] and [2] both feature characters who will do whatever it takes to " ++
  "get to their goal, and in the end the thing they want the most ends " ++
  "up destroying them.  In case of [2], this is a whale..."

-- Function that will take a list of Strings and return a list that contains
-- any String of the type [n], where n is an variable
ref :: [String] -> [String]
ref [] = []
ref xs = [x | x <- xs, head x == '[', last x == ']']

-- Function takes a text with references in the format [n] and returns
-- the total number of references.
-- Example :  ghci> references txt -- -> 3
references :: String -> Integer   
references txt = len (ref (words txt))

如果有人能告诉我如何在字符串中搜索子字符串 或如何解析给定子字符串的字符串,将不胜感激。

【问题讨论】:

    标签: string parsing haskell substring extract


    【解决方案1】:

    我会用一个正则表达式,这样写:

    import Text.Regex.Posix
    
    txt :: String
    txt = "[1] and [2] both feature characters who will do whatever it takes to " ++
      "get to their goal, and in the end the thing they want the most ends " ++
      "up destroying them.  In case of [2], this is a whale..."
    
    
    -- references counts the number of references in the input string
    references :: String -> Int
    references str = str =~ "\\[[0-9]*\\]"
    
    main = putStrLn $ show $ references txt -- outputs 3
    

    【讨论】:

    • 感谢 jcarpenter!您介意解释一下 =~ 运算符的作用吗?那是导入库的一部分吗?我更希望弄清楚每当 [n] 发生时如何解析,因为我想最终用一个字符串替换每个 [n] ,该字符串位于由任何 n 索引的列表中。
    • 我不知道 =~ 在内部是如何工作的。它将正则表达式与字符串匹配,并且可以返回各种不同的类型。谷歌或其他人可以比我更详细地阐述它。
    【解决方案2】:

    正则表达式对于这样一个简单的问题来说太过分了。

    references = length . consume
    
    consume []       = []
    consume ('[':xs) = let (v,rest) = consume' xs in v:consume rest
    consume (_  :xs) = consume xs
    
    consume' []       = ([], []) 
    consume' (']':xs) = ([], xs)
    consume' (x  :xs) = let (v,rest) = consume' xs in (x:v, rest)
    

    consume 等待[,然后调用consume',它会收集所有内容,直到]

    【讨论】:

    • 我更喜欢这个而不是其他答案,因为 A)它是 Haskell 中的简洁解决方案,而不是正则表达式;和 B)这可能更容易理解和修改 OP 的用例。
    【解决方案3】:

    这是一个解决方案 sepCap.

    import Replace.Megaparsec
    import Text.Megaparsec
    import Text.Megaparsec.Char
    import Data.Either
    import Data.Maybe
    
    txt = "[1] and [2] both feature characters who will do whatever it takes to " ++
      "get to their goal, and in the end the thing they want the most ends " ++
      "up destroying them.  In case of [2], this is a whale..."
    
    pattern = single '[' *> anySingle <* single ']' :: Parsec Void String Char
    length $ rights $ fromJust $ parseMaybe (sepCap pattern) txt
    
    3
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-21
      • 1970-01-01
      • 1970-01-01
      • 2018-09-29
      • 2021-12-23
      • 1970-01-01
      • 2018-07-07
      相关资源
      最近更新 更多