lens-regex-pcre-0.2.0.0

Copyright(c) Chris Penner 2019
LicenseBSD3
Safe HaskellNone
LanguageHaskell2010

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

Combinators

regex :: Regex -> Traversal' Text Match Source #

The base combinator for doing regex searches. It's a traversal which selects Matches; 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"

iregex :: Regex -> IndexedTraversal' Int Text Match Source #

regex but indexed with match number

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

Types

type Match = [Either Text Text] Source #

Match represents a whole regex match; you can drill into it using match or groups or matchAndGroups Consider this to be internal; don't depend on its representation.