on 577fc17 help sign in
elk/libraries/Regex.elm
126 lines 4.3 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 regex, escape, caseInsensitive
8# Helpful Data Structures
10These data structures are needed to help define functions like [`find`](#find)
11and [`replace`](#replace).
13@docs HowMany, Match
15# Use
16@docs contains, find, replace, split
18-}
20import Maybe (Maybe)
21import Native.Regex
23data Regex = Regex
25{-| Escape strings to be regular expressions, making all special characters
26safe. So `regex (escape "^a+")` will match exactly `"^a+"` instead of a series
27of `a`’s that start at the beginning of the line.
28-}
29escape : String -> String
30escape = Native.Regex.escape
32{-| 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).
34Be careful to escape backslashes properly! For example, `"\w"` is escaping the
35letter `w` which is probably not what you want. You probably want `"\\w"`
36instead, which escapes the backslash.
37-}
38regex : String -> Regex
39regex = Native.Regex.regex
42{-| Make a regex case insensitive -}
43caseInsensitive : Regex -> Regex
44caseInsensitive = Native.Regex.caseInsensitive
46{-| Check to see if a Regex is contained in a string.
48```haskell
49 contains (regex "123") "12345" == True
50 contains (regex "b+") "aabbcc" == True
52 contains (regex "789") "12345" == False
53 contains (regex "z+") "aabbcc" == False
54```
55-}
56contains : Regex -> String -> Bool
57contains = Native.Regex.contains
59{-| A `Match` represents all of the details about a particular match in a string.
60Here are details on each field:
62 * `match` — the full string of the match.
63 * `submatches` — a regex might have [subpatterns, surrounded by
64 parentheses](https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions#Using_Parenthesized_Substring_Matches).
65 If there are N subpatterns, there will be N elements in the `submatches` list.
66 Each submatch in this list is a `Maybe` because not all subpatterns may trigger.
67 For example, `(regex "(a+)|(b+)")` will either match many `a`’s or
68 many `b`’s, but never both.
69 * `index` — the index of the match in the original string.
70 * `number` — if you find many matches, you can think of each one
71 as being labeled with a `number` starting at one. So the first time you
72 find a match, that is match `number` one. Second time is match `number` two.
73 This is useful when paired with `replace All` if replacement is dependent on how
74 many times a pattern has appeared before.
75-}
76type Match = { match : String, submatches : [Maybe String], index : Int, number : Int }
78{-| `HowMany` is used to specify how many matches you want to make. So
79`replace All` would replace every match, but `replace (AtMost 2)` would
80replace at most two matches (i.e. zero, one, two, but never three or more).
81-}
82data HowMany = All | AtMost Int
84{-| Find matches in a string:
86```haskell
87 findTwoCommas = find (AtMost 2) (regex ",")
89 -- map .index (findTwoCommas "a,b,c,d,e") == [1,3]
90 -- map .index (findTwoCommas "a b c d e") == []
92 places = find All (regex "[oi]n a (\\w+)") "I am on a boat in a lake."
94 -- map .match places == ["on a boat", "in a lake"]
95 -- map .submatches places == [ [Just "boat"], [Just "lake"] ]
96```
97-}
98find : HowMany -> Regex -> String -> [Match]
99find = Native.Regex.find
101{-| Replace matches. The function from `Match` to `String` lets
102you use the details of a specific match when making replacements.
104```haskell
105 devowel = replace All (regex "[aeiou]") (\_ -> "")
107 -- devowel "The quick brown fox" == "Th qck brwn fx"
109 reverseWords = replace All (regex "\\w+") (\{match} -> String.reverse match)
111 -- reverseWords "deliver mined parts" == "reviled denim strap"
112```
113-}
114replace : HowMany -> Regex -> (Match -> String) -> String -> String
115replace = Native.Regex.replace
117{-| Split a string, using the regex as the separator.
119```haskell
120 split (AtMost 1) (regex ",") "tom,99,90,85" == ["tom","99,90,85"]
122 split All (regex ",") "a,b,c,d" == ["a","b","c","d"]
123```
124-}
125split : HowMany -> Regex -> String -> [String]
126split = Native.Regex.split