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; they 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]
- matchAndGroups :: Getter Match (Text, [Text])
- rx :: QuasiQuoter
- type Match = [Either Text Text]
Combinators
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.
txt :: Text txt = "raindrops on roses and whiskers on kittens"
Search
λ> has (regex [rx|whisk|]) txt True
Get matches
λ> txt ^.. regex [rx|\br\w+|] . match ["raindrops","roses"]
Edit matches
λ> txt & regex [rx|\br\w+|] . match %~ T.intersperse '-' . T.toUpper "R-A-I-N-D-R-O-P-S on R-O-S-E-S and whiskers on kittens"
Get Groups
λ> txt ^.. regex [rx|(\w+) on (\w+)|] . groups [["raindrops","roses"],["whiskers","kittens"]]
Edit Groups
λ> txt & regex [rx|(\w+) on (\w+)|] . groups %~ reverse "roses on raindrops and kittens on whiskers"
Get the third match
λ> txt ^? iregex [rx|\w+|] . index 2 . match Just "roses"
Match integers, Read
them into ints, then sort them in-place
dumping them back into the source text afterwards.
λ> "Monday: 29, Tuesday: 99, Wednesday: 3" & partsOf (iregex [rx|\d+|] . match . unpacked . _Show @Int) %~ sort "Monday: 3, Tuesday: 29, Wednesday: 99"
match :: Traversal' Match Text Source #
Traverse each match
Get a match if one exists:
λ> "find a needle in a haystack" ^? regex [rx|n..dle|] . match Just "needle"
Collect all matches
λ> "one _two_ three _four_" ^.. regex [rx|_\w+_|] . match ["_two_","_four_"]
You can edit the traversal to perform a regex replace/substitution
λ> "one _two_ three _four_" & regex [rx|_\w+_|] . match %~ T.toUpper "one _TWO_ three _FOUR_"
groups :: Traversal' Match [Text] Source #
Access all groups of a match at once.
Note that you can edit the groups through this traversal,
Changing the length of the list has behaviour similar to partsOf
.
Get all matched groups:
λ> "raindrops on roses and whiskers on kittens" ^.. regex [rx|(\w+) on (\w+)|] . groups [["raindrops","roses"],["whiskers","kittens"]]
You can access a specific group by combining with ix
λ> "raindrops on roses and whiskers on kittens" ^.. regex [rx|(\w+) on (\w+)|] . groups . ix 1 ["roses", "kittens"]
groups
is a traversal; you can mutate matches through it.
λ> "raindrops on roses and whiskers on kittens" & regex [rx|(\w+) on (\w+)|] . groups . ix 1 %~ T.toUpper "raindrops on ROSES and whiskers on KITTENS"
Editing the list rearranges groups
λ> "raindrops on roses and whiskers on kittens" & regex [rx|(\w+) on (\w+)|] . groups %~ reverse "roses on raindrops and kittens on whiskers"
You can traverse the list to flatten out all groups
λ> "raindrops on roses and whiskers on kittens" ^.. regex [rx|(\w+) on (\w+)|] . groups . traversed ["raindrops","roses","whiskers","kittens"]
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