regex :: Regex -> IndexedTraversal' Int BS.ByteString MatchIt's a traversal which selects Matches; compose it with match or groups to get the relevant parts of your match.
>>> txt = "raindrops on roses and whiskers on kittens"Search
>>> has ([regex|whisk|]) txt TrueGet matches
>>> txt ^.. [regex|\br\w+|] . match ["raindrops","roses"]Edit matches
>>> txt & [regex|\br\w+|] . match %~ Char8.intersperse '-' . Char8.map toUpper "R-A-I-N-D-R-O-P-S on R-O-S-E-S and whiskers on kittens"Get Groups
>>> txt ^.. [regex|(\w+) on (\w+)|] . groups [["raindrops","roses"],["whiskers","kittens"]]Edit Groups
>>> txt & [regex|(\w+) on (\w+)|] . groups %~ reverse "roses on raindrops and kittens on whiskers"Get the third match
>>> txt ^? [regex|\w+|] . index 2 . match Just "roses"Edit matches
>>> txt & [regex|\br\w+|] . match %~ Char8.intersperse '-' . Char8.map toUpper "R-A-I-N-D-R-O-P-S on R-O-S-E-S and whiskers on kittens"Get Groups
>>> txt ^.. [regex|(\w+) on (\w+)|] . groups [["raindrops","roses"],["whiskers","kittens"]]Edit Groups
>>> txt & [regex|(\w+) on (\w+)|] . groups %~ reverse "roses on raindrops and kittens on whiskers"Get the third match
>>> txt ^? [regex|\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 ([regex|\d+|] . match . from packedChars . _Show @Int) %~ sort "Monday: 3, Tuesday: 29, Wednesday: 99"To alter behaviour of the regex you may wish to pass PCREOptions when compiling it. The default behaviour may seem strange in certain cases; e.g. it operates in 'single-line' mode. You can compile the Regex separately and add any options you like, then pass the resulting Regex into regex; Alternatively can make your own version of the QuasiQuoter with any options you want embedded by using mkRegexQQ.
regex :: Regex -> IndexedTraversal' Int T.Text MatchIt's a traversal which selects Matches; compose it with match or groups to get the relevant parts of your match.
>>> txt = "raindrops on roses and whiskers on kittens"Search
>>> has ([regex|whisk|]) txt TrueGet matches
>>> txt ^.. [regex|\br\w+|] . match ["raindrops","roses"]Edit matches
>>> txt & [regex|\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|(\w+) on (\w+)|] . groups [["raindrops","roses"],["whiskers","kittens"]]Edit Groups
>>> txt & [regex|(\w+) on (\w+)|] . groups %~ reverse "roses on raindrops and kittens on whiskers"Get the third match
>>> txt ^? [regex|\w+|] . index 2 . match Just "roses"Edit matches
>>> txt & [regex|\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|(\w+) on (\w+)|] . groups [["raindrops","roses"],["whiskers","kittens"]]Edit Groups
>>> txt & [regex|(\w+) on (\w+)|] . groups %~ reverse "roses on raindrops and kittens on whiskers"Get the third match
>>> txt ^? [regex|\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 ([regex|\d+|] . match . unpacked . _Show @Int) %~ sort "Monday: 3, Tuesday: 29, Wednesday: 99"To alter behaviour of the regex you may wish to pass PCREOptions when compiling it. The default behaviour may seem strange in certain cases; e.g. it operates in 'single-line' mode. You can compile the Regex separately and add any options you like, then pass the resulting Regex into regex; Alternatively can make your own version of the QuasiQuoter with any options you want embedded by using mkRegexQQ. regex :: Regex -> IndexedTraversal' Int T.Text RBS.Match
>>> "foo bar baz" ^? regex [r|b.*r|] Just (MatchPart {_matchedString = "bar", _captures = []})
>>> "foo bar baz" ^? regex [r|hoge|] NothingYou can access to the matched string by using matchedString:
>>> "foo bar baz" ^? regex [r|b.*r|] . matchedString Just "bar"Multiple result:
>>> "foo bar baz" ^.. regex [r|b[^ ]+|] . matchedString ["bar","baz"]Replace:
>>> "foo bar baz" & regex [r|b[^ ]+|] . matchedString .~ "nya" "foo nya nya"Indexing:
>>> "foo bar baz" ^.. regex [r|b[^ ]+|] . index 1 . matchedString ["baz"]
>>> "foo bar baz" & regex [r|b[^ ]+|] . index 1 . matchedString .~ "nya" "foo bar nya"Captures:
>>> "foo00 bar01 baz02" ^.. regex [r|([a-z]+)([0-9]+)|] . captures [["foo","00"],["bar","01"],["baz","02"]]
>>> "foo00 bar01 baz02" ^.. regex [r|([a-z]+)([0-9]+)|] . captures . traversed . index 1 ["00","01","02"]Note: This is not a legal Traversal, unless you are very careful not to invalidate the predicate on the target. For example, if you replace the matched part with a string which is not match with the regex, the second Traversal law is violated.
let l = regex [r|t.*t|] . matchedString over l (++ "peta") . over l (++ "nya") /= over l ((++ "peta") . (++ "nya")) over l (++ "put") . over l (++ "hot") == over l ((++ "put") . (++ "hot"))
regex :: (Alternative f) => String -> Text -> f (Captures info)if there are parenthesized captures, or
regex :: (Alternative f) => String -> Text -> f Textif there are none. In other words, if there is more than the 0th capture, this behaves like captures (except returning an opaque Captures instead of a NonEmpty list), otherwise it behaves like match. To retrieve an individual capture from a Captures, use capture.
case [regex|(?<y>\d{4})-(?<m>\d{2})-(?<d>\d{2})|] "submitted 2020-10-20" of Just cs -> let date = capture @0 cs year = read @Int $ Text.unpack $ capture @"y" cs ...
forM_ @Maybe ([regex|\s+$|] line) $ \spaces -> printf "line has trailing spaces (%d characters)\n" (Text.length spaces)
case "submitted 2020-10-20" of [regex|(?<y>\d{4})-(?<m>\d{2})-(?<d>\d{2})|] -> let year = read @Int $ Text.unpack y ...Note that it is not possible to access the 0th capture this way. As a workaround, explicitly capture the whole pattern and name it. If there are no named captures, this simply acts as a guard.