pcre-heavy: A regexp library on top of pcre-light you can actually use.

[ library, public-domain, web ] [ Propose Tags ]
Versions 0.1.0, 0.2.0, 0.2.1, 0.2.2, 0.2.3, 0.2.4, 0.2.5, 1.0.0,,
Dependencies base (>= && <5), base‑compat (>=0.8.0), bytestring, pcre‑light, semigroups, string‑conversions, template‑haskell [details]
License LicenseRef-PublicDomain
Copyright 2015 Greg V <greg@unrelenting.technology>
Author Greg V
Maintainer greg@unrelenting.technology
Category Web
Home page https://github.com/myfreeweb/pcre-heavy
Source repo head: git clone git://github.com/myfreeweb/pcre-heavy.git
Uploaded by myfreeweb at Tue Mar 15 21:42:59 UTC 2016
Distributions Arch:, LTSHaskell:, NixOS:, Stackage:, openSUSE:
Downloads 3758 total (47 in the last 30 days)
Rating 2.0 (votes: 1) [estimated by rule of succession]
Your Rating
  • λ
  • λ
  • λ
Status Docs available [build log]
Last success reported on 2016-03-15 [all 1 reports]
Hackage Matrix CI

A regular expressions library that does not suck. Based on pcre-light. Takes and returns Stringables everywhere. Includes a QuasiQuoter for regexps that does compile time checking. SEARCHES FOR MULTIPLE MATCHES! DOES REPLACEMENT!

[Skip to Readme]




Maintainer's Corner

For package maintainers and hackage trustees

Readme for pcre-heavy-

[back to package description]

pcre-heavy Hackage Build Status unlicense

Finally! A Haskell regular expressions library that does not suck.

  • based on pcre-light, none of that regex-base complicated pluggable-backend stuff
  • takes and returns ConvertibleStrings everywhere, use ANY STRING TYPE (String, ByteString, Lazy ByteString, Text, Lazy Text) -- but you need a bit more type annotations (or ClassyPrelude's asText, asString, etc.) if you use OverloadedStrings which you probably can't live without
  • a QuasiQuoter for regexps that does compile time checking (BTW, vim2hs has correct syntax highlighting for that!)


{-# LANGUAGE QuasiQuotes, FlexibleContexts #-}
import           Text.Regex.PCRE.Heavy


>>> "https://unrelenting.technology" =~ [re|^http.*|]

For UnicodeSyntax fans, it's also available as ≈ (U+2248 ALMOST EQUAL TO):

>>> "https://unrelenting.technology" ≈ [re|^http.*|]

Matching (Searching)

(You can use any string type, not just String!)

scan returns all matches as pairs like (fullmatch, [group, group...]).

>>> scan [re|\s*entry (\d+) (\w+)\s*&?|] " entry 1 hello  &entry 2 hi" :: [(String, [String])]
  (" entry 1 hello  &", ["1", "hello"])
, ("entry 2 hi",        ["2", "hi"])

It is lazy! If you only need the first match, use head (or, much better, headMay from safe) -- no extra work will be performed!

>>> headMay $ scan [re|\s*entry (\d+) (\w+)\s*&?|] " entry 1 hello  &entry 2 hi"
Just (" entry 1 hello  &", ["1", "hello"])


sub replaces the first match, gsub replaces all matches.

-- You can use a Stringable type as the replacement...
>>> gsub [re|\d+|] "!!!NUMBER!!!" "Copyright (c) 2015 The 000 Group"
"Copyright (c) !!!NUMBER!!! The !!!NUMBER!!! Group"

-- or a (Stringable a => [a] -> a) function -- that will get the groups...
>>> gsub [re|%(\d+)(\w+)|] (\(d:w:_) -> "{" ++ d ++ " of " ++ w ++ "}" :: String) "Hello, %20thing"
"Hello, {20 of thing}"

-- or a (Stringable a => a -> a) function -- that will get the full match...
>>> gsub [re|-\w+|] (\x -> "+" ++ (reverse $ drop 1 x) :: String) "hello -world"
"hello +dlrow"

-- or a (Stringable a => a -> [a] -> a) function.
-- That will get both the full match and the groups.
-- I have no idea why you would want to use that, but that's there :-)


split, well, splits.

>>> split [re|%(begin|next|end)%|] "%begin%hello%next%world%end%"


You can pass pcre-light options by using the somethingO variants of functions (and mkRegexQQ for compile time options):

>>> let myRe = mkRegexQQ [multiline, utf8, ungreedy]
>>> scanO [myRe|\s*entry (\d+) (\w+)\s*&?|] [exec_no_utf8_check] " entry 1 hello  &entry 2 hi" :: [[String]]
>>> gsubO [myRe|\d+|] [exec_notempty] "!!!NUMBER!!!" "Copyright (c) 2015 The 000 Group"

utf8 is passed by default in the re QuasiQuoter.


Use stack to build.
Use ghci to run tests quickly with :test (see the .ghci file).

$ stack build

$ stack test && rm tests.tix

$ stack ghci --ghc-options="-fno-hpc"


Please feel free to submit pull requests! Bugfixes and simple non-breaking improvements will be accepted without any questions :-)

By participating in this project you agree to follow the Contributor Code of Conduct.


This is free and unencumbered software released into the public domain.
For more information, please refer to the UNLICENSE file or unlicense.org.