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