lens-regex-pcre-0.1.1.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; the break the 'multi-set' idempotence law; in reality this isn't usually a problem; but consider yourself warned. Test your code.

Synopsis

Documentation

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.

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"

match :: Traversal' Match Text Source #

Traverse each match as a whole

Use with regex or iregex

> "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 #

traverse each group within a match. See igroups for selecting specific groups or grouped for handling all groups at once.

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

type Match = [Either Text Text] Source #

Match represents a whole regex match; you can drill into it using match or groups