@@ -115,6 +115,7 @@ module Data.Text
115 , stripEnd
115 , stripEnd
116 , splitAt
116 , splitAt
118 , breakBy
119 , breakBy
120 , groupBy
121 , groupBy
@@ -124,7 +125,6 @@ module Data.Text
124 -- ** Breaking into many substrings
125 -- ** Breaking into many substrings
125 -- $split
126 -- $split
128 , splitTimesEnd
128 , splitTimesEnd
129 , splitBy
129 , splitBy
130 , chunksOf
130 , chunksOf
@@ -1051,35 +1051,62 @@ filter :: (Char -> Bool) -> Text -> Text
1051filter p t = unstream (S.filter p (stream t))
1051filter p t = unstream (S.filter p (stream t))
1052{-# INLINE filter #-}
1052{-# INLINE filter #-}
1054−-- /O(n+m)/ Find all non-overlapping instances of @needle@ in
1054+-- | /O(n+m)/ Find the first instance of @needle@ in @haystack@. The
1055−-- @haystack@. The first element of the returned tuple is the prefix
1055+-- first element of the returned tuple is the prefix of @haystack@
1056−-- of @haystack@ before any matches of @needle@. The second element
1056+-- before @needle@ is matched. The second is the remainder of
1057−-- of the tuple is a list of non-overlapping substrings from
1057+-- @haystack@, starting with the match.
1058−-- @haystack@. Each begins with @needle@ and ends just before the
1059−-- following match. If @needle@ is not present in @haystack@, the
1060−-- list will be empty and the prefix will contain @haystack@.
1062-- Examples:
1059-- Examples:
1064−-- > find "::" "a::b::c" ==> ("a", ["::b", "::c"])
1061+-- > break "::" "a::b::c" ==> ("a", "::b::c")
1065−-- > find "/" "foobar" ==> ("foobar", [])
1062+-- > break "/" "foobar" ==> ("foobar", "")
1069−-- > concat (prefix : matches) == haystack
1066+-- > append prefix match == haystack
1070−-- > where (prefix, matches) = find needle haystack
1067+-- > where (prefix, match) = break needle haystack
1069+-- If you need to break a string by a substring repeatedly (e.g. you
1070+-- want to break on every instance of a substring), use 'find'
1071+-- instead, as it has lower startup overhead.
1072-- In (unlikely) bad cases, this function's time complexity
1073-- In (unlikely) bad cases, this function's time complexity
1073-- degenerates towards /O(n*m)/.
1074-- degenerates towards /O(n*m)/.
1075+break :: Text -> Text -> (Text, Text)
1076+break pat src@(Text arr off len)
1077+ | null pat = emptyError "break"
1078+ | otherwise = case indices pat src of
1080+ (x:_) -> (textP arr off x, textP arr (off+x) (len-x))
1081+{-# INLINE break #-}
1083+-- | /O(n+m)/ Find all non-overlapping instances of @needle@ in
1084+-- @haystack@. The first element of the returned pair is the prefix
1085+-- of @haystack@ prior to any matches of @needle@. The second is a
1088+-- The first element of each pair in the list is a span from the
1089+-- beginning of a match to the beginning of the next match, while the
1090+-- second is a span from the beginning of the match to the end of the
1097+-- > find "/" "a/b/c/d"
1098+-- > ==> ("a", [("/b","/b/c/d"), ("/c","/c/d"), ("/d","/d")])
1074−find :: Text -> Text -> (Text, [Text])
1099+find :: Text -> Text -> (Text, [(Text, Text)])
1075find pat src@(Text arr off len)
1100find pat src@(Text arr off len)
1076 | null pat = emptyError "find"
1101 | null pat = emptyError "find"
1077 | otherwise = case indices pat src of
1102 | otherwise = case indices pat src of
1078 [] -> (src, [])
1103 [] -> (src, [])
1079− (x:xs) -> (textP arr off x, go x xs)
1104+ (x:xs) -> (chunk 0 x, go x xs)
1081− go !s (x:xs) = textP arr (s+off) (x-s) : go x xs
1106+ go !s (x:xs) = (chunk s (x-s), chunk s (len-s)) : go x xs
1082− go s _ = [textP arr (s+off) (len-s)]
1107+ go s _ = let c = chunk s (len-s)
1109+ chunk !n !l = textP arr (n+off) l
1083{-# INLINE find #-}
1110{-# INLINE find #-}
1085-------------------------------------------------------------------------------
1112-------------------------------------------------------------------------------
@@ -1099,8 +1126,7 @@ find pat src@(Text arr off len)
1099-- For example, suppose you have a string that you want to split on
1126-- For example, suppose you have a string that you want to split on
1100-- the substring @\"::\"@, such as @\"foo::bar::quux\"@. Instead of
1127-- the substring @\"::\"@, such as @\"foo::bar::quux\"@. Instead of
1101-- searching for the index of @\"::\"@ and taking the substrings
1128-- searching for the index of @\"::\"@ and taking the substrings
1102−-- before and after that index, you would instead use @splitTimes 1
1129+-- before and after that index, you would instead use @find "::"@.
1105-- | /O(n)/ 'Text' index (subscript) operator, starting from 0.
1131-- | /O(n)/ 'Text' index (subscript) operator, starting from 0.
1106index :: Text -> Int -> Char
1132index :: Text -> Int -> Char