如何在Haskell中搜索某些文本?

时间:2018-01-11 00:20:44

标签: string haskell

我如何从Python中执行Haskell等效操作?

>>> "this is a test".find("test")
10

编辑:基本上我有一些文字,例如:“这是一个测试”。现在我有一个我想在该文本中找到的字符串,例如:“test”。如何在“这是一个测试”中找到“测试”的字符偏移量?

3 个答案:

答案 0 :(得分:6)

如果你想要高速的东西,那么你将需要使用Text(压缩字节)而不是String(链接的字符列表)。文本还有一个略微隐藏的指示函数,用于:

Prelude> :set -XOverloadedStrings
Prelude> import Data.Text
Prelude Data.Text> import Data.Text.Internal.Search
Prelude Data.Text Data.Text.Internal.Search> indices "yep" "yep no yes yep"
[0,11]

镜像另一个回答者的命名,并提供一些变体来给出一个数字,匹配索引列表(可能是空的),以及一个可能的版本:

{-# LANGUAGE OverloadedStrings #-}
import Data.Text.Internal.Search
import Data.Text

findString :: Text -> Text -> [Int]
findString = indices

findStringMaybe :: Text -> Text -> Maybe Int
findStringMaybe x str = case indices x str of
                         (idx:_) -> Just idx
                         _ -> Nothing

findStringWithNegOne :: Text -> Text -> Int
findStringWithNegOne x str = maybe (-1) id (findStringMaybe x str)

答案 1 :(得分:4)

您可以尝试使用ListActivity中的findIndexisPrefixOf

ListActivity

其工作原理如下:

Select D1.Col as Header, D2.Col as Price, D3.Col as [Valid Until], D4.Col as [Posted On], D5.col as Visit, D6.col as Replies, D7.Col as PageNo

From dataTable D1
    inner join dataTable D2 on D2.ID = D1.ID + 1
    inner join dataTable D3 on D3.ID = D1.ID + 2
    inner join dataTable D4 on D4.ID = D1.ID + 3
    inner join dataTable D5 on D5.ID = D1.ID + 4
    inner join dataTable D6 on D6.ID = D1.ID + 5            
    inner join dataTable D7 on D7.ID = D1.ID + 6

Where D1.ID % 7 = 1  --Mod 7

此外,由于Data.List类型为:import Data.List findString :: (Eq a) => [a] -> [a] -> Maybe Int findString search str = findIndex (isPrefixOf search) (tails str) ,因此此处会返回*Main> findString "test" "this is a test" Just 10 *Main> findString "blah" "this is a test" Nothing findIndex。如果它返回findIndex :: (a -> Bool) -> [a] -> Maybe Int,则找不到子字符串,否则返回Just Int。这是Haskell方法,是这里最常规的返回类型。

注意:如果您确实想要返回Nothing,请使用pythons str.find()方法,您可以将上述功能调整为:

Nothing

使用Just Int中的fromMaybe-1转换为import Data.List import Data.Maybe findString :: (Eq a) => [a] -> [a] -> Int findString search str = fromMaybe (-1) $ findIndex (isPrefixOf search) (tails str) ,将Data.Maybe转换为Nothing

答案 2 :(得分:1)

这是我的做法:

findSubStrIdx :: String -> String -> Integer -> Maybe Integer
findSubStrIdx "" _ _ = Nothing
findSubStrIdx s target n
    | take (length target) s == target      = n
    | otherwise                             = findSubStrIdx (tail s) target (n + 1)

这种方法不像其他方法那么抽象,这取决于您是在编写库还是在做其他事情,这可能是好事还是坏事。比一些更抽象的方法更了解。我认为这不会引发任何例外。要启动,请为整数输入0,如下所示:

findSubStrIdx "hi, my name is Joe" "Joe" 0

,您应该得到如下结果:

Just 15

现在考虑长字符串中不存在您要查找的字符串的情况:

findSubStrIdx "hi, my name is Joe" "Harry" 0
Nothing

如果您想使用fromMaybe之类的东西,我建议您在调用此函数的地方使用它;这样,您可以减少引发未处理异常的风险。如果您真的想做C风格的-1事情,可以这样做:

cStyleNegative1 :: Maybe Integer -> Integer
cStyleNegative1 Nothing = -1
cStyleNegative1 (Just x) = x

但是,正如其他人所说,我建议您不要这样做。