String 用一个字符串拆分一个字符串

String 用一个字符串拆分一个字符串,string,parsing,haskell,String,Parsing,Haskell,我正在尝试使用Haskell构造一个lexer分析器,我需要构造一个函数f::String->String->(String,String),它将输入拆分为一个字符串元组。函数需要按已知字符串拆分。已知字符串始终位于要分析的字符串的开头 例如,如果要拆分的字符串是“expression”,而输入是“expression rest of String”,我需要生成一个输出(“expression”,“rest of String”) 我试图避免使用高级库 有什么帮助吗 谢谢。好了: f :: St

我正在尝试使用Haskell构造一个lexer分析器,我需要构造一个函数
f::String->String->(String,String)
,它将输入拆分为一个字符串元组。函数需要按已知字符串拆分。已知字符串始终位于要分析的字符串的开头

例如,如果要拆分的字符串是“expression”,而输入是“expression rest of String”,我需要生成一个输出(“expression”,“rest of String”)

我试图避免使用高级库

有什么帮助吗

谢谢。

好了:

f :: String -> String -> [String]

f sep src = f_ src []
  where
    f_ [] acc = [reverse acc]
    f_ (x:xs) acc =
      case stripPrefix sep (x:xs) of
        Nothing  -> f_ xs (x:acc)
        Just rem -> [reverse acc] ++ [sep] ++ f_ rem []
好了:

f :: String -> String -> [String]

f sep src = f_ src []
  where
    f_ [] acc = [reverse acc]
    f_ (x:xs) acc =
      case stripPrefix sep (x:xs) of
        Nothing  -> f_ xs (x:acc)
        Just rem -> [reverse acc] ++ [sep] ++ f_ rem []

您还需要以某种方式处理失败,例如返回一个Maybe。您似乎还希望在余数的开头消除空白

import Data.Char (isSpace)
import Data.List (stripPrefix)

f :: String -> String -> Maybe String
f prefix = fmap (dropWhile isSpace) . stripPrefix prefix

g :: String -> String -> (String, Maybe String)
g prefix str = (prefix, f prefix str)

h :: String -> String -> Maybe (String, String)
h prefix str = case f prefix str of 
  Nothing -> Nothing
  Just rest -> Just (prefix, rest)


-- >>> f "expression" "expression rest of string"
-- Just "rest of string"
-- >>> g "expression" "expression rest of string"
-- ("expression",Just "rest of string")
-- >>> h "expression" "expression rest of string"
-- Just ("expression","rest of string")

-- >>> f "expression" "xpression rest of string"
-- Nothing
-- >>> g "expression" "xpression rest of string"
-- ("expression",Nothing)
-- >>> h "expression" "xpression rest of string"
-- Nothing
这有点像大多数解析器库中的
string
解析器,其类型类似于
string->parser string
——如果找到字符串,它将返回该字符串,如果没有,则返回失败。最简单的版本附带ghc,不是“高级库”

 >>> import Text.ParserCombinators.ReadP
 >>> let apply = readP_to_S 
 >>> apply (string "expression") "expression rest of string"
 [("expression"," rest of string")]
 >>> apply (string "expression") "xpression rest of string"
 []
 >>> let myParser = string "expression" >> skipSpaces
 >>> apply myParser "expression rest of string"
 [((),"rest of string")]
 >>> apply myParser "xpression rest of string"
 []
 >>> let myBetterParser = do {exp <- string "expression" ; skipSpaces ; return exp}
 >>> apply myBetterParser "expression rest of string"
 [("expression","rest of string")]
 >>> apply myBetterParser "xpression rest of string"
 []
导入Text.ParserCombinators.ReadP >>>让apply=readP_to_S >>>应用(字符串“表达式”)“表达式字符串的其余部分” [(“表达式”,“字符串的其余部分”)] >>>应用(字符串“表达式”)“xpression字符串的其余部分” [] >>>让myParser=string“expression”>>skipSpaces >>>应用myParser“字符串的其余表达式” [((),“字符串的其余部分”)] >>>应用myParser“xpression剩余字符串” [] >>>让myBetterParser=do{exp>>应用myBetterParser“字符串的其余表达式” [(“表达式”,“字符串的其余部分”)] >>>应用myBetterParser“xpression字符串的其余部分” []
您还需要以某种方式处理失败,例如返回一个Maybe。您似乎还希望在剩余部分的开头消除空白

import Data.Char (isSpace)
import Data.List (stripPrefix)

f :: String -> String -> Maybe String
f prefix = fmap (dropWhile isSpace) . stripPrefix prefix

g :: String -> String -> (String, Maybe String)
g prefix str = (prefix, f prefix str)

h :: String -> String -> Maybe (String, String)
h prefix str = case f prefix str of 
  Nothing -> Nothing
  Just rest -> Just (prefix, rest)


-- >>> f "expression" "expression rest of string"
-- Just "rest of string"
-- >>> g "expression" "expression rest of string"
-- ("expression",Just "rest of string")
-- >>> h "expression" "expression rest of string"
-- Just ("expression","rest of string")

-- >>> f "expression" "xpression rest of string"
-- Nothing
-- >>> g "expression" "xpression rest of string"
-- ("expression",Nothing)
-- >>> h "expression" "xpression rest of string"
-- Nothing
这有点像大多数解析器库中的
string
解析器,其类型类似于
string->parser string
——如果找到字符串,它会返回字符串,如果找不到则会失败。最简单的版本是ghc,不是“高级库”

 >>> import Text.ParserCombinators.ReadP
 >>> let apply = readP_to_S 
 >>> apply (string "expression") "expression rest of string"
 [("expression"," rest of string")]
 >>> apply (string "expression") "xpression rest of string"
 []
 >>> let myParser = string "expression" >> skipSpaces
 >>> apply myParser "expression rest of string"
 [((),"rest of string")]
 >>> apply myParser "xpression rest of string"
 []
 >>> let myBetterParser = do {exp <- string "expression" ; skipSpaces ; return exp}
 >>> apply myBetterParser "expression rest of string"
 [("expression","rest of string")]
 >>> apply myBetterParser "xpression rest of string"
 []
导入Text.ParserCombinators.ReadP >>>让apply=readP_to_S >>>应用(字符串“表达式”)“表达式字符串的其余部分” [(“表达式”,“字符串的其余部分”)] >>>应用(字符串“表达式”)“xpression字符串的其余部分” [] >>>让myParser=string“expression”>>skipSpaces >>>应用myParser“字符串的其余表达式” [((),“字符串的其余部分”)] >>>应用myParser“xpression剩余字符串” [] >>>让myBetterParser=do{exp>>应用myBetterParser“字符串的其余表达式” [(“表达式”,“字符串的其余部分”)] >>>应用myBetterParser“xpression字符串的其余部分” []
类型不适合这个问题。另外,如果较短的字符串不是较长字符串的前缀怎么办?@larsmans我正在考虑对已知字符串进行硬编码,但我可以更改类型以通过参数接收。有关如何实现此函数的任何帮助?这不只是
f prefix s=(prefix,drop(len prefix)s)吗
?还是我遗漏了什么?(我仍然遗漏了前缀不匹配时会发生什么情况——你说它总是匹配的,但是为什么你需要这个函数?)类型不适合这个问题。另外,如果较短的字符串不是较长字符串的前缀怎么办?@larsmans我正在考虑将已知字符串硬编码,但我可以更改类型以通过参数接收。有关如何实现此函数的任何帮助?这不只是
f prefix s=(prefix,drop(len prefix)s)吗
?还是我遗漏了什么?(我仍然遗漏了前缀不匹配时会发生什么情况——你说它总是匹配的,但是为什么你需要这个函数?)