Copyright | (c) Chris Penner 2019 |
---|---|
License | BSD3 |
Safe Haskell | None |
Language | Haskell2010 |
Control.Lens.Regex
Contents
Description
Note that all traversals in this library are not techically lawful; the break the 'multi-set' idempotence law; in reality this isn't usually a problem; but consider yourself warned. Test your code.
Synopsis
- regex :: Regex -> Traversal' Text Match
- iregex :: Regex -> IndexedTraversal' Int Text Match
- match :: Traversal' Match Text
- groups :: Traversal' Match Text
- igroups :: IndexedTraversal' Int Match Text
- grouped :: Traversal' Match [Text]
- matchAndGroups :: Getter Match (Text, [Text])
- rx :: QuasiQuoter
- type Match = [Either Text Text]
Documentation
regex :: Regex -> Traversal' Text Match Source #
The base combinator for doing regex searches.
It's a traversal which selects Match
es; you can compose it with match
or groups
to get the relevant parts of your match.
Getting all matches:
> "one _two_ three _four_" ^.. regex [rx|_\w+_|] . match ["_two_","_four_"]
Regex replace/mutation
> "one _two_ three _four_" & regex [rx|_\w+_|] . match %~ T.toUpper "one _TWO_ three _FOUR_"
Getting groups with their group index.
> "1/2 and 3/4" ^.. regex [rx|(\d+)/(\d+)|] . igroups . withIndex [(0,"1"),(1,"2"),(0,"3"),(1,"4")]
Check for any matches:
> has (regex [rx|ne+dle|]) "a needle in a haystack" True
Check for matches which also match a predicate:
> has (regex [rx|\w+|] . match . filtered ((> 7) . T.length)) "one word here is loooooooong" True
Get the third match
> "alpha beta charlie delta" ^? (iregex [rx|\w+|] . index 2 . match) Just "charlie"
Replace the third match
> "alpha beta charlie delta" & (iregex [rx|\w+|] . index 2 . match) .~ "GAMMA" "alpha beta GAMMA delta"
Match integers, Read
them into ints, then sort each match in-place
> "Monday: 29, Tuesday: 99, Wednesday: 3" & partsOf' (iregex [rx|\d+|] . match . unpacked . _Show @Int) %~ sort "Monday: 3, Tuesday: 29, Wednesday: 99"
igroups :: IndexedTraversal' Int Match Text Source #
groups
but indexed by the group number. If you traverse over many matches you will
encounter duplicate indices.
E.g.
> "a 1 b 2" ^.. regex [rx|(\w) (\d)|] . igroups . withIndex [(0,"a"),(1,"1"),(0,"b"),(1,"2")]
If you want only a specific group; combine this with index
E.g.
> "a 1 b 2" ^.. regex [rx|(\w) (\d)|] . igroups . index 0 ["a","b"]
grouped :: Traversal' Match [Text] Source #
Access all groups of a match at once.
Note that this uses partsOf
; and is only a valid traversal if you don't
alter the length of the list. It is valid as a Fold or Getter however.
> "raindrops on roses and whiskers on kittens" ^.. regex [rx|(\w+) on (\w+)|] . grouped [["raindrops","roses"],["whiskers","kittens"]]
> "raindrops on roses and whiskers on kittens" & regex [rx|(\w+) on (\w+)|] . grouped %~ reverse "roses on raindrops and kittens on whiskers"
matchAndGroups :: Getter Match (Text, [Text]) Source #
Collect both the match text AND all the matching groups
> "raindrops on roses and whiskers on kittens" ^.. regex [rx|(\w+) on (\w+)|] . matchAndGroups [ ("raindrops on roses", ["raindrops","roses"]) , ("whiskers on kittens", ["whiskers","kittens"]) ]
QuasiQuoter
rx :: QuasiQuoter Source #
QuasiQuoter
for compiling regexes.
This is just re
re-exported under a different name so as not to conflict with re
from
Lens