[project @ 2003-04-17 15:17:07 by simonpj]
[ghc-base.git] / Text / Regex.hs
1 -----------------------------------------------------------------------------
2 -- |
3 -- Module      :  Text.Regex
4 -- Copyright   :  (c) The University of Glasgow 2001
5 -- License     :  BSD-style (see the file libraries/base/LICENSE)
6 -- 
7 -- Maintainer  :  libraries@haskell.org
8 -- Stability   :  experimental
9 -- Portability :  non-portable (only on platforms that provide a regex lib)
10 --
11 -- Regular expression matching.  Uses the POSIX regular expression
12 -- interface in "Text.Regex.Posix".
13 --
14 -----------------------------------------------------------------------------
15
16 module Text.Regex (
17     -- * Regular expressions
18     Regex,
19     mkRegex,
20     mkRegexWithOpts,
21     matchRegex,
22     matchRegexAll
23   ) where
24
25 import Prelude
26 import qualified Text.Regex.Posix as RE
27 import System.IO.Unsafe
28
29 -- | A compiled regular expression
30 type Regex = RE.Regex
31
32 -- | Makes a regular expression with the default options (multi-line,
33 -- case-sensitive).  The syntax of regular expressions is
34 -- otherwise that of @egrep@ (i.e. POSIX \"extended\" regular
35 -- expressions).
36 mkRegex :: String -> Regex
37 mkRegex s = unsafePerformIO (RE.regcomp s RE.regExtended)
38
39 -- | Makes a regular expression, where the multi-line and
40 -- case-sensitve options can be changed from the default settings.
41 mkRegexWithOpts
42    :: String  -- ^ The regular expression to compile
43    -> Bool    -- ^ 'True' @\<=>@ '@^@' and '@$@' match the beginning and 
44               -- end of individual lines respectively, and '.' does /not/
45               -- match the newline character.
46    -> Bool    -- ^ 'True' @\<=>@ matching is case-sensitive
47    -> Regex   -- ^ Returns: the compiled regular expression
48
49 mkRegexWithOpts s single_line case_sensitive
50    = unsafePerformIO (RE.regcomp s (RE.regExtended + newline + igcase))
51    where
52         newline | single_line = 0
53                 | otherwise   = RE.regNewline
54
55         igcase  | case_sensitive = 0 
56                 | otherwise      = RE.regIgnoreCase
57
58 -- | Match a regular expression against a string
59 matchRegex
60    :: Regex     -- ^ The regular expression
61    -> String    -- ^ The string to match against
62    -> Maybe [String]    -- ^ Returns: @'Just' strs@ if the match succeeded
63                         -- (and @strs@ is the list of subexpression matches),
64                         -- or 'Nothing' otherwise.
65 matchRegex p str = 
66   case (unsafePerformIO (RE.regexec p str)) of
67         Nothing -> Nothing
68         Just (before, match, after, sub_strs) -> Just sub_strs
69
70 -- | Match a regular expression against a string, returning more information
71 -- about the match.
72 matchRegexAll
73    :: Regex     -- ^ The regular expression
74    -> String    -- ^ The string to match against
75    -> Maybe ( String, String, String, [String] )
76                 -- ^ Returns: 'Nothing' if the match failed, or:
77                 -- 
78                 -- >  Just ( everything before match,
79                 -- >         portion matched,
80                 -- >         everything after the match,
81                 -- >         subexpression matches )
82
83 matchRegexAll p str = unsafePerformIO (RE.regexec p str)
84