Text.Regex.Applicative

regex-applicative-0.3.4: Regex-based parsing with applicative interface

Copyright | (c) Roman Cheplyaka
License | MIT
Maintainer | Roman Cheplyaka <roma@ro-che.info>
Stability | experimental
Safe Haskell | Safe-Inferred
Language | Haskell2010

Text.Regex.Applicative

Contents

- Custom uncons function

Description

To get started, see some examples on the wiki: https://github.com/feuerbach/regex-applicative/wiki/Examples

Synopsis

- data RE s a
- sym :: Eq s => s -> RE s s
- psym :: (s -> Bool) -> RE s s
- msym :: (s -> Maybe a) -> RE s a
- anySym :: RE s s
- string :: Eq a => [a] -> RE a [a]
- reFoldl :: Greediness -> (b -> a -> b) -> b -> RE s a -> RE s b
- data Greediness
  - = Greedy
  - | NonGreedy
- few :: RE s a -> RE s [a]
- comap :: (s2 -> s1) -> RE s1 a -> RE s2 a
- withMatched :: RE s a -> RE s (a, [s])
- match :: RE s a -> [s] -> Maybe a
- (=~) :: [s] -> RE s a -> Maybe a
- replace :: RE s [s] -> [s] -> [s]
- findFirstPrefix :: RE s a -> [s] -> Maybe (a, [s])
- findLongestPrefix :: RE s a -> [s] -> Maybe (a, [s])
- findShortestPrefix :: RE s a -> [s] -> Maybe (a, [s])
- findFirstInfix :: RE s a -> [s] -> Maybe ([s], a, [s])
- findLongestInfix :: RE s a -> [s] -> Maybe ([s], a, [s])
- findShortestInfix :: RE s a -> [s] -> Maybe ([s], a, [s])
- findFirstPrefixWithUncons :: (ss -> Maybe (s, ss)) -> RE s a -> ss -> Maybe (a, ss)
- findLongestPrefixWithUncons :: (ss -> Maybe (s, ss)) -> RE s a -> ss -> Maybe (a, ss)
- findShortestPrefixWithUncons :: (ss -> Maybe (s, ss)) -> RE s a -> ss -> Maybe (a, ss)
- module Control.Applicative

# Documentation

data RE s a #

Type of regular expressions that recognize symbols of type `s` and produce a result of type `a`.

Regular expressions can be built using `Functor`, `Applicative`, `Alternative`, and `Filtrable` instances in the following natural way:

- `f` `<$>` `ra` matches iff `ra` matches, and its return value is the result of applying `f` to the return value of `ra`.
- `pure` `x` matches the empty string (i.e. it does not consume any symbols), and its return value is `x`
- `rf` `<*>` `ra` matches a string iff it is a concatenation of two strings: one matched by `rf` and the other matched by `ra`. The return value is `f a`, where `f` and `a` are the return values of `rf` and `ra` respectively.
- `ra` `<|>` `rb` matches a string which is accepted by either `ra` or `rb`. It is left-biased, so if both can match, the result of `ra` is used.
- `empty` is a regular expression which does not match any string.
- `many` `ra` matches concatenation of zero or more strings matched by `ra` and returns the list of `ra`'s return values on those strings.
- `some` `ra` matches concatenation of one or more strings matched by `ra` and returns the list of `ra`'s return values on those strings.
- `catMaybes` `ram` matches iff `ram` matches and produces 'Just _'.
- `ra` `<>` `rb` matches `ra` followed by `rb`. The return value is `a <> b`, where `a` and `b` are the return values of `ra` and `rb` respectively. (See https://github.com/feuerbach/regex-applicative/issues/37#issue-499781703 for an example usage.)
- `mempty` matches the empty string (i.e. it does not consume any symbols), and its return value is the `mempty` value of type `a`.

#### Instances

Instances details

Filtrable (RE s) # | Since: 0.3.4
Instance details Defined in Text.Regex.Applicative.Types Methods mapMaybe :: (a -> Maybe b) -> RE s a -> RE s b # catMaybes :: RE s (Maybe a) -> RE s a # filter :: (a -> Bool) -> RE s a -> RE s a # mapMaybeA :: (Traversable (RE s), Applicative p) => (a -> p (Maybe b)) -> RE s a -> p (RE s b) # filterA :: (Traversable (RE s), Applicative p) => (a -> p Bool) -> RE s a -> p (RE s a) # mapEither :: (a -> Either b c) -> RE s a -> (RE s b, RE s c) # mapEitherA :: (Traversable (RE s), Applicative p) => (a -> p (Either b c)) -> RE s a -> p (RE s b, RE s c) # partitionEithers :: RE s (Either a b) -> (RE s a, RE s b) #
Alternative (RE s) # |
Instance details Defined in Text.Regex.Applicative.Types Methods empty :: RE s a # (<|>) :: RE s a -> RE s a -> RE s a # some :: RE s a -> RE s [a] # many :: RE s a -> RE s [a] #
Applicative (RE s) # |
Instance details Defined in Text.Regex.Applicative.Types Methods pure :: a -> RE s a # (<*>) :: RE s (a -> b) -> RE s a -> RE s b # liftA2 :: (a -> b -> c) -> RE s a -> RE s b -> RE s c # (*>) :: RE s a -> RE s b -> RE s b # (<*) :: RE s a -> RE s b -> RE s a #
Functor (RE s) # |
Instance details Defined in Text.Regex.Applicative.Types Methods fmap :: (a -> b) -> RE s a -> RE s b # (<$) :: a -> RE s b -> RE s a #
Monoid a => Monoid (RE s a) # | Since: 0.3.4
Instance details Defined in Text.Regex.Applicative.Types Methods mempty :: RE s a # mappend :: RE s a -> RE s a -> RE s a # mconcat :: [RE s a] -> RE s a #
Semigroup a => Semigroup (RE s a) # | Since: 0.3.4
Instance details Defined in Text.Regex.Applicative.Types Methods (<>) :: RE s a -> RE s a -> RE s a # sconcat :: NonEmpty (RE s a) -> RE s a # stimes :: Integral b => b -> RE s a -> RE s a #
(char ~ Char, string ~ String) => IsString (RE char string) # |
Instance details Defined in Text.Regex.Applicative.Types Methods fromString :: String -> RE char string #

sym :: Eq s => s -> RE s s #

Match and return the given symbol

psym :: (s -> Bool) -> RE s s #

Match and return a single symbol which satisfies the predicate

msym :: (s -> Maybe a) -> RE s a #

Like `psym`, but allows to return a computed value instead of the original symbol

anySym :: RE s s #

Match and return any single symbol

string :: Eq a => [a] -> RE a [a] #

Match and return the given sequence of symbols.

Note that there is an `IsString` instance for regular expression, so if you enable the `OverloadedStrings` language extension, you can write `string "foo"` simply as `"foo"`.

Example:

    {-# LANGUAGE OverloadedStrings #-}
    import Text.Regex.Applicative

    number = "one" *> pure 1  <|>  "two" *> pure 2

    main = print $ "two" =~ number

reFoldl :: Greediness -> (b -> a -> b) -> b -> RE s a -> RE s b #

Match zero or more instances of the given expression, which are combined using the given folding function.

`Greediness` argument controls whether this regular expression should match as many as possible (`Greedy`) or as few as possible (`NonGreedy`) instances of the underlying expression.

data Greediness #

Constructors

Greedy |
NonGreedy |

#### Instances

Instances details

Enum Greediness # |
Instance details Defined in Text.Regex.Applicative.Types Methods succ :: Greediness -> Greediness # pred :: Greediness -> Greediness # toEnum :: Int -> Greediness # fromEnum :: Greediness -> Int # enumFrom :: Greediness -> [Greediness] # enumFromThen :: Greediness -> Greediness -> [Greediness] # enumFromTo :: Greediness -> Greediness -> [Greediness] # enumFromThenTo :: Greediness -> Greediness -> Greediness -> [Greediness] #
Read Greediness # |
Instance details Defined in Text.Regex.Applicative.Types Methods readsPrec :: Int -> ReadS Greediness # readList :: ReadS [Greediness] # readPrec :: ReadPrec Greediness # readListPrec :: ReadPrec [Greediness] #
Show Greediness # |
Instance details Defined in Text.Regex.Applicative.Types Methods showsPrec :: Int -> Greediness -> ShowS # show :: Greediness -> String # showList :: [Greediness] -> ShowS #
Eq Greediness # |
Instance details Defined in Text.Regex.Applicative.Types Methods (==) :: Greediness -> Greediness -> Bool # (/=) :: Greediness -> Greediness -> Bool #
Ord Greediness # |
Instance details Defined in Text.Regex.Applicative.Types Methods compare :: Greediness -> Greediness -> Ordering # (<) :: Greediness -> Greediness -> Bool # (<=) :: Greediness -> Greediness -> Bool # (>) :: Greediness -> Greediness -> Bool # (>=) :: Greediness -> Greediness -> Bool # max :: Greediness -> Greediness -> Greediness # min :: Greediness -> Greediness -> Greediness #

few :: RE s a -> RE s [a] #

Match zero or more instances of the given expression, but as few of them as possible (i.e. non-greedily). A greedy equivalent of `few` is `many`.

Examples:

    Text.Regex.Applicative> findFirstPrefix (few anySym  <* "b") "ababab"
    Just ("a","abab")
    Text.Regex.Applicative> findFirstPrefix (many anySym  <* "b") "ababab"
    Just ("ababa","")

comap :: (s2 -> s1) -> RE s1 a -> RE s2 a #

`RE` is a profunctor. This is its contravariant map.

(A dependency on the `profunctors` package doesn't seem justified.)

withMatched :: RE s a -> RE s (a, [s]) #

Return matched symbols as part of the return value

match :: RE s a -> [s] -> Maybe a #

Attempt to match a string of symbols against the regular expression. Note that the whole string (not just some part of it) should be matched.

Examples:

    Text.Regex.Applicative> match (sym 'a' <|> sym 'b') "a"
    Just 'a'
    Text.Regex.Applicative> match (sym 'a' <|> sym 'b') "ab"
    Nothing

(=~) :: [s] -> RE s a -> Maybe a infix 2 #

    s =~ a = match a s

replace :: RE s [s] -> [s] -> [s] #

Replace matches of the regular expression with its value.

    Text.Regex.Applicative > replace ("!" <$ sym 'f' <* some (sym 'o')) "quuxfoofooooofoobarfobar"
    "quux!!!bar!bar"

findFirstPrefix :: RE s a -> [s] -> Maybe (a, [s]) #

Find a string prefix which is matched by the regular expression.

Of all matching prefixes, pick one using left bias (prefer the left part of `<|>` to the right part) and greediness.

This is the match which a backtracking engine (such as Perl's one) would find first.

If match is found, the rest of the input is also returned.

See also `findFirstPrefixWithUncons`, of which this is a special case.

Examples:

    Text.Regex.Applicative> findFirstPrefix ("a" <|> "ab") "abc"
    Just ("a","bc")
    Text.Regex.Applicative> findFirstPrefix ("ab" <|> "a") "abc"
    Just ("ab","c")
    Text.Regex.Applicative> findFirstPrefix "bc" "abc"
    Nothing

findLongestPrefix :: RE s a -> [s] -> Maybe (a, [s]) #

Find the longest string prefix which is matched by the regular expression.

Submatches are still determined using left bias and greediness, so this is different from POSIX semantics.

If match is found, the rest of the input is also returned.

See also `findLongestPrefixWithUncons`, of which this is a special case.

Examples:

    Text.Regex.Applicative Data.Char> let keyword = "if"
    Text.Regex.Applicative Data.Char> let identifier = many $ psym isAlpha
    Text.Regex.Applicative Data.Char> let lexeme = (Left <$> keyword) <|> (Right <$> identifier)
    Text.Regex.Applicative Data.Char> findLongestPrefix lexeme "if foo"
    Just (Left "if"," foo")
    Text.Regex.Applicative Data.Char> findLongestPrefix lexeme "iffoo"
    Just (Right "iffoo","")

findShortestPrefix :: RE s a -> [s] -> Maybe (a, [s]) #

Find the shortest prefix (analogous to `findLongestPrefix`)

See also `findShortestPrefixWithUncons`, of which this is a special case.

findFirstInfix :: RE s a -> [s] -> Maybe ([s], a, [s]) #

Find the leftmost substring that is matched by the regular expression. Otherwise behaves like `findFirstPrefix`. Returns the result together with the prefix and suffix of the string surrounding the match.

findLongestInfix :: RE s a -> [s] -> Maybe ([s], a, [s]) #

Find the leftmost substring that is matched by the regular expression. Otherwise behaves like `findLongestPrefix`. Returns the result together with the prefix and suffix of the string surrounding the match.

findShortestInfix :: RE s a -> [s] -> Maybe ([s], a, [s]) #

Find the leftmost substring that is matched by the regular expression. Otherwise behaves like `findShortestPrefix`. Returns the result together with the prefix and suffix of the string surrounding the match.

# Custom uncons function

The following functions take an argument that splits the input into the first symbol and the remaining input (if the input is non-empty).

It is useful, for example, for feeding a `Text` to a regex matcher:

    >>> findFirstPrefixWithUncons Text.uncons (many (sym 'a')) "aaa"
    Just ("aaa", "")

For another example, feeding input symbols annotated with source positions into a matcher, preserving the positions in the remaining input so the location of a lexical error can be recovered:

    data AList a b = AList { annotation :: a, stripAnnotation :: Maybe (b, AList a b) }

    findLongestPrefixAnnotated :: RE s a -> AList b s -> Maybe (a, AList b s)
    fondLongestPrefixAnnotated = findLongestPrefixWithUncons stripAnnotation

The use of the other functions taking an `uncons` argument is exactly analogous.

findFirstPrefixWithUncons :: (ss -> Maybe (s, ss)) -> RE s a -> ss -> Maybe (a, ss) #

Find the first prefix, with the given `uncons` function.

Since: 0.3.4

findLongestPrefixWithUncons :: (ss -> Maybe (s, ss)) -> RE s a -> ss -> Maybe (a, ss) #

Find the longest prefix, with the given `uncons` function.

Since: 0.3.4

findShortestPrefixWithUncons :: (ss -> Maybe (s, ss)) -> RE s a -> ss -> Maybe (a, ss) #

Find the shortest prefix (analogous to `findLongestPrefix`), with the given `uncons` function.

Since: 0.3.4

module Control.Applicative