forked from elm/core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRegex.elm
148 lines (105 loc) · 4.48 KB
/
Regex.elm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
module Regex
( Regex
, regex, escape, caseInsensitive
, HowMany(..), Match
, contains, find, replace, split
) where
{-| A library for working with regular expressions. It uses [the
same kind of regular expressions accepted by JavaScript](https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions).
# Create
@docs Regex, regex, escape, caseInsensitive
# Helpful Data Structures
These data structures are needed to help define functions like [`find`](#find)
and [`replace`](#replace).
@docs HowMany, Match
# Use
@docs contains, find, replace, split
-}
import Maybe exposing (Maybe)
import Native.Regex
{-| A regular expression, describing a certain set of strings.
-}
type Regex = Regex
{-| Escape strings to be regular expressions, making all special characters
safe. So `regex (escape "^a+")` will match exactly `"^a+"` instead of a series
of `a`’s that start at the beginning of the line.
-}
escape : String -> String
escape =
Native.Regex.escape
{-| 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).
Be careful to escape backslashes properly! For example, `"\w"` is escaping the
letter `w` which is probably not what you want. You probably want `"\\w"`
instead, which escapes the backslash.
-}
regex : String -> Regex
regex =
Native.Regex.regex
{-| Make a regex case insensitive -}
caseInsensitive : Regex -> Regex
caseInsensitive =
Native.Regex.caseInsensitive
{-| Check to see if a Regex is contained in a string.
contains (regex "123") "12345" == True
contains (regex "b+") "aabbcc" == True
contains (regex "789") "12345" == False
contains (regex "z+") "aabbcc" == False
-}
contains : Regex -> String -> Bool
contains =
Native.Regex.contains
{-| A `Match` represents all of the details about a particular match in a string.
Here are details on each field:
* `match` — the full string of the match.
* `submatches` — a regex might have [subpatterns, surrounded by
parentheses](https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions#Using_Parenthesized_Substring_Matches).
If there are N subpatterns, there will be N elements in the `submatches` list.
Each submatch in this list is a `Maybe` because not all subpatterns may trigger.
For example, `(regex "(a+)|(b+)")` will either match many `a`’s or
many `b`’s, but never both.
* `index` — the index of the match in the original string.
* `number` — if you find many matches, you can think of each one
as being labeled with a `number` starting at one. So the first time you
find a match, that is match `number` one. Second time is match `number` two.
This is useful when paired with `replace All` if replacement is dependent on how
many times a pattern has appeared before.
-}
type alias Match =
{ match : String
, submatches : List (Maybe String)
, index : Int
, number : Int
}
{-| `HowMany` is used to specify how many matches you want to make. So
`replace All` would replace every match, but `replace (AtMost 2)` would
replace at most two matches (i.e. zero, one, two, but never three or more).
-}
type HowMany = All | AtMost Int
{-| Find matches in a string:
findTwoCommas = find (AtMost 2) (regex ",")
-- map .index (findTwoCommas "a,b,c,d,e") == [1,3]
-- map .index (findTwoCommas "a b c d e") == []
places = find All (regex "[oi]n a (\\w+)") "I am on a boat in a lake."
-- map .match places == ["on a boat", "in a lake"]
-- map .submatches places == [ [Just "boat"], [Just "lake"] ]
-}
find : HowMany -> Regex -> String -> List Match
find =
Native.Regex.find
{-| Replace matches. The function from `Match` to `String` lets
you use the details of a specific match when making replacements.
devowel = replace All (regex "[aeiou]") (\_ -> "")
-- devowel "The quick brown fox" == "Th qck brwn fx"
reverseWords = replace All (regex "\\w+") (\{match} -> String.reverse match)
-- reverseWords "deliver mined parts" == "reviled denim strap"
-}
replace : HowMany -> Regex -> (Match -> String) -> String -> String
replace =
Native.Regex.replace
{-| Split a string, using the regex as the separator.
split (AtMost 1) (regex ",") "tom,99,90,85" == ["tom","99,90,85"]
split All (regex ",") "a,b,c,d" == ["a","b","c","d"]
-}
split : HowMany -> Regex -> String -> List String
split =
Native.Regex.split