on c7a1069 help sign in
78 lines 2.6 kB history raw
1{-# LANGUAGE FlexibleContexts #-}
2--------------------------------------------------------------------------------
3-- | Miscellaneous string manipulation functions.
4module Hakyll.Core.Util.String
5 ( trim
6 , replaceAll
7 , splitAll
8 , needlePrefix
9 ) where
12--------------------------------------------------------------------------------
13import Data.Char (isSpace)
14import Data.List (isPrefixOf)
15import Data.Maybe (listToMaybe)
16import Text.Regex.TDFA ((=~~))
19--------------------------------------------------------------------------------
20-- | Trim a string (drop spaces, tabs and newlines at both sides).
21trim :: String -> String
22trim = reverse . trim' . reverse . trim'
23 where
24 trim' = dropWhile isSpace
27--------------------------------------------------------------------------------
28-- | A simple (but inefficient) regex replace funcion
29replaceAll :: String -- ^ Pattern
30 -> (String -> String) -- ^ Replacement (called on capture)
31 -> String -- ^ Source string
32 -> String -- ^ Result
33replaceAll pattern f source = replaceAll' source
34 where
35 replaceAll' src = case listToMaybe (src =~~ pattern) of
36 Nothing -> src
37 Just (o, l) ->
38 let (before, tmp) = splitAt o src
39 (capture, after) = splitAt l tmp
40 in before ++ f capture ++ replaceAll' after
43--------------------------------------------------------------------------------
44-- | A simple regex split function. The resulting list will contain no empty
45-- strings.
46splitAll :: String -- ^ Pattern
47 -> String -- ^ String to split
48 -> [String] -- ^ Result
49splitAll pattern = filter (not . null) . splitAll'
50 where
51 splitAll' src = case listToMaybe (src =~~ pattern) of
52 Nothing -> [src]
53 Just (o, l) ->
54 let (before, tmp) = splitAt o src
55 in before : splitAll' (drop l tmp)
59--------------------------------------------------------------------------------
60-- | Find the first instance of needle (must be non-empty) in haystack. We
61-- return the prefix of haystack before needle is matched.
62--
63-- Examples:
64--
65-- > needlePrefix "cd" "abcde" = "ab"
66--
67-- > needlePrefix "ab" "abc" = ""
68--
69-- > needlePrefix "ab" "xxab" = "xx"
70--
71-- > needlePrefix "a" "xx" = "xx"
72needlePrefix :: String -> String -> Maybe String
73needlePrefix needle haystack = go [] haystack
74 where
75 go _ [] = Nothing
76 go acc xss@(x:xs)
77 | needle `isPrefixOf` xss = Just $ reverse acc
78 | otherwise = go (x : acc) xs