on 63243ca help sign in
elk/libraries/Regex.elm
133 lines 4.4 kB history raw
1module Regex where
2{-| A library for working with regular expressions. It uses [the
3same kind of regular expressions accepted by JavaScript](https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions).
5# Create
6@docs pattern, caseInsensitive, escape
8# Match
9@docs Match
11# Find and Replace
12@docs contains, find, findAll, replace, replaceAll
14# Split
15@docs split, splitN
17-}
19import Maybe (Maybe)
20import Native.Regex
22data Regex = Regex
24{-| Escape all special characters. So `pattern (escape "$$$")`
25will match exactly `"$$$"` even though `$` is a special character.
26-}
27escape : String -> String
28escape = Native.Regex.escape
30{-| Create a Regex that matches patterns [as specified in JavaScript](https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions#Writing_a_Regular_Expression_Pattern).
31Be careful to escape backslashes properly!
32-}
33pattern : String -> Regex
34pattern = Native.Regex.pattern
37{-| Make a pattern case insensitive -}
38caseInsensitive : Regex -> Regex
39caseInsensitive = Native.Regex.caseInsensitive
41{-| Check to see if a Regex is contained in a string.
43```haskell
44 contains (pattern "123") "12345" == True
45 contains (pattern "b+") "aabbcc" == True
47 contains (pattern "789") "12345" == False
48 contains (pattern "z+") "aabbcc" == False
49```
50-}
51contains : Regex -> String -> Bool
52contains = Native.Regex.contains
54{-| A `Match` represents all of the details about a particular match in a string.
55Here are details on each field:
57 * `match` — the full string of the match.
58 * `submatches` — a pattern might have [subpatterns, surrounded by
59 parentheses](https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions#Using_Parenthesized_Substring_Matches).
60 If there are N subpatterns, there will be N elements in the `submatches` list.
61 Each submatch in this list is a `Maybe` because not all subpatterns may trigger.
62 For example, `(pattern "(a+)|(b+)")` will either match many `a`’s or
63 many `b`’s, but never both.
64 * `index` — the index of the match in the original string.
65 * `number` — if you find many matches, you can think of each one
66 as being labeled with a `number` starting at one. So the first time you
67 find a match, that is match `number` one. Second time is match `number` two.
68 This is useful when paired with `replaceAll` if replacement is dependent on how
69 many times a pattern has appeared before.
70-}
71type Match = { match : String, submatches : [Maybe String], index : Int, number : Int }
73{-| Find all of the matches in a string:
75```haskell
76 words = findAll (pattern "\\w+") "hello world"
78 map .match words == ["hello","world"]
79 map .index words == [0,6]
81 places = findAll (pattern "[oi]n a (\\w+)") "I am on a boat in a lake."
83 map .match places== ["on a boat", "in a lake"]
84 map .submatches places == [ [Just "boat"], [Just "lake"] ]
85```
86-}
87findAll : Regex -> String -> [Match]
88findAll = Native.Regex.findAll
90{-| Same as `findAll`, but `find` will quit searching after the *n<sup>th</sup>* match.
91That means the resulting list has maximum length N, but *it can be shorter*
92if there are not that many matches in the given string.
93-}
94find : Int -> Regex -> String -> [Match]
95find = Native.Regex.find
97{-| Replace all matches. The function from `Match` to `String` lets
98you use the details of a specific match when making replacements.
100```haskell
101 devowel = replaceAll (pattern "[aeiou]") (\_ -> "")
103 devowel "The quick brown fox" == "Th qck brwn fx"
105 reverseWords = replaceAll (pattern "\\w+") (\{match} -> String.reverse match)
107 reverseWords "deliver mined parts" == "reviled denim strap"
108```
109-}
110replaceAll : Regex -> (Match -> String) -> String -> String
111replaceAll = Native.Regex.replaceAll
113{-| Same as `replaceAll`, but `replace` will quit after the *n<sup>th</sup>* match.-}
114replace : Int -> Regex -> (Match -> String) -> String -> String
115replace = Native.Regex.replace
117{-| Split a string, using the regex as the separator.
119```haskell
120 split (pattern " *, *") "a ,b, c,d" == ["a","b","c","d"]
121```
122-}
123split : Regex -> String -> [String]
124split = Native.Regex.split
126{-| Same as `split` but stops after the *n<sup>th</sup>* match.
128```haskell
129 splitN 1 (pattern ": *") "tom: 99,90,85" == ["tom","99,90,85"]
130```
131-}
132splitN : Int -> Regex -> String -> [String]
133splitN = Native.Regex.splitN