@@ -15,17 +15,20 @@ module Text.Parsing.StringParser.String
15
15
, upperCaseChar
16
16
, anyLetter
17
17
, alphaNum
18
+ , regex
18
19
) where
19
20
20
21
import Prelude
21
22
22
23
import Control.Alt ((<|>))
23
- import Data.Array ((..))
24
+ import Data.Array ((..), uncons )
24
25
import Data.Char (toCharCode )
25
26
import Data.Either (Either (..))
26
27
import Data.Foldable (class Foldable , foldMap , elem , notElem )
27
- import Data.Maybe (Maybe (..))
28
- import Data.String (Pattern (..), charAt , length , indexOf' , singleton )
28
+ import Data.Maybe (Maybe (..), fromMaybe )
29
+ import Data.String (Pattern (..), charAt , drop , length , indexOf' , singleton , stripPrefix )
30
+ import Data.String.Regex as Regex
31
+ import Data.String.Regex.Flags (noFlags )
29
32
import Text.Parsing.StringParser (Parser (..), ParseError (..), try , fail )
30
33
import Text.Parsing.StringParser.Combinators (many , (<?>))
31
34
@@ -111,3 +114,31 @@ anyLetter = lowerCaseChar <|> upperCaseChar <?> "Expected a letter"
111
114
-- | Match a letter or a number.
112
115
alphaNum :: Parser Char
113
116
alphaNum = anyLetter <|> anyDigit <?> " Expected a letter or a number"
117
+
118
+ -- | match the regular expression
119
+ regex :: String -> Parser String
120
+ regex pat =
121
+ case Regex .regex pattern noFlags of
122
+ Left _ ->
123
+ fail $ " Text.Parsing.StringParser.String.regex': illegal regex " <> pat
124
+ Right r ->
125
+ matchRegex r
126
+ where
127
+ -- ensure the pattern only matches the current position in the parse
128
+ pattern =
129
+ case stripPrefix (Pattern " ^" ) pat of
130
+ Nothing ->
131
+ " ^" <> pat
132
+ _ ->
133
+ pat
134
+ matchRegex :: Regex.Regex -> Parser String
135
+ matchRegex r =
136
+ Parser \{ str, pos } ->
137
+ let
138
+ remainder = drop pos str
139
+ in
140
+ case uncons $ fromMaybe [] $ Regex .match r remainder of
141
+ Just { head: Just matched, tail: _ } ->
142
+ Right { result: matched, suffix: { str, pos: pos + length matched } }
143
+ _ ->
144
+ Left { pos, error: ParseError " no match" }
0 commit comments