Skip to content

Commit 3f7ad6f

Browse files
Risto-Stevcevgaryb
authored andcommitted
Added some shortcuts for commonly used flags (purescript#67)
* Added a monoid instance and helper functions to regex flags * Refactored the regex flags code
1 parent 2e60399 commit 3f7ad6f

File tree

4 files changed

+103
-24
lines changed

4 files changed

+103
-24
lines changed

src/Data/String/Regex.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ exports.source = function (r) {
2525
return r.source;
2626
};
2727

28-
exports.flags = function (r) {
28+
exports["flags'"] = function (r) {
2929
return {
3030
multiline: r.multiline,
3131
ignoreCase: r.ignoreCase,

src/Data/String/Regex.purs

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
-- | For details of the underlying implementation, see [RegExp Reference at MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp).
44
module Data.String.Regex
55
( Regex(..)
6-
, RegexFlags(..)
76
, regex
87
, source
98
, flags
@@ -15,14 +14,14 @@ module Data.String.Regex
1514
, replace'
1615
, search
1716
, split
18-
, noFlags
1917
) where
2018

2119
import Prelude
2220

2321
import Data.Either (Either(..))
2422
import Data.Maybe (Maybe(..))
2523
import Data.String (contains)
24+
import Data.String.Regex.Flags (RegexFlags(..), RegexFlagsRec)
2625

2726
-- | Wraps Javascript `RegExp` objects.
2827
foreign import data Regex :: *
@@ -32,23 +31,6 @@ foreign import showRegex' :: Regex -> String
3231
instance showRegex :: Show Regex where
3332
show = showRegex'
3433

35-
-- | Flags that control matching.
36-
type RegexFlags =
37-
{ global :: Boolean
38-
, ignoreCase :: Boolean
39-
, multiline :: Boolean
40-
, sticky :: Boolean
41-
, unicode :: Boolean
42-
}
43-
44-
-- | All flags set to false.
45-
noFlags :: RegexFlags
46-
noFlags = { global : false
47-
, ignoreCase : false
48-
, multiline : false
49-
, sticky : false
50-
, unicode : false }
51-
5234
foreign import regex' :: (String -> Either String Regex)
5335
-> (Regex -> Either String Regex)
5436
-> String
@@ -64,11 +46,15 @@ regex s f = regex' Left Right s $ renderFlags f
6446
foreign import source :: Regex -> String
6547

6648
-- | Returns the `RegexFlags` used to construct the given `Regex`.
67-
foreign import flags :: Regex -> RegexFlags
49+
flags :: Regex -> RegexFlags
50+
flags = RegexFlags <<< flags'
51+
52+
-- | Returns the `RegexFlags` inner record used to construct the given `Regex`.
53+
foreign import flags' :: Regex -> RegexFlagsRec
6854

6955
-- | Returns the string representation of the given `RegexFlags`.
7056
renderFlags :: RegexFlags -> String
71-
renderFlags f =
57+
renderFlags (RegexFlags f) =
7258
(if f.global then "g" else "") <>
7359
(if f.ignoreCase then "i" else "") <>
7460
(if f.multiline then "m" else "") <>
@@ -77,7 +63,7 @@ renderFlags f =
7763

7864
-- | Parses the string representation of `RegexFlags`.
7965
parseFlags :: String -> RegexFlags
80-
parseFlags s =
66+
parseFlags s = RegexFlags
8167
{ global: contains "g" s
8268
, ignoreCase: contains "i" s
8369
, multiline: contains "m" s

src/Data/String/Regex/Flags.purs

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
module Data.String.Regex.Flags where
2+
3+
import Prelude (class Semigroup, (||))
4+
import Data.Monoid (class Monoid)
5+
6+
type RegexFlagsRec =
7+
{ global :: Boolean
8+
, ignoreCase :: Boolean
9+
, multiline :: Boolean
10+
, sticky :: Boolean
11+
, unicode :: Boolean
12+
}
13+
14+
-- | Flags that control matching.
15+
data RegexFlags = RegexFlags RegexFlagsRec
16+
17+
-- | All flags set to false.
18+
noFlags :: RegexFlags
19+
noFlags = RegexFlags
20+
{ global: false
21+
, ignoreCase: false
22+
, multiline: false
23+
, sticky: false
24+
, unicode: false
25+
}
26+
27+
-- | Only global flag set to true
28+
global :: RegexFlags
29+
global = RegexFlags
30+
{ global: true
31+
, ignoreCase: false
32+
, multiline: false
33+
, sticky: false
34+
, unicode: false
35+
}
36+
37+
-- | Only ignoreCase flag set to true
38+
ignoreCase :: RegexFlags
39+
ignoreCase = RegexFlags
40+
{ global: false
41+
, ignoreCase: true
42+
, multiline: false
43+
, sticky: false
44+
, unicode: false
45+
}
46+
47+
-- | Only multiline flag set to true
48+
multiline :: RegexFlags
49+
multiline = RegexFlags
50+
{ global: false
51+
, ignoreCase: false
52+
, multiline: true
53+
, sticky: false
54+
, unicode: false
55+
}
56+
57+
-- | Only sticky flag set to true
58+
sticky :: RegexFlags
59+
sticky = RegexFlags
60+
{ global: false
61+
, ignoreCase: false
62+
, multiline: false
63+
, sticky: true
64+
, unicode: false
65+
}
66+
67+
-- | Only unicode flag set to true
68+
unicode :: RegexFlags
69+
unicode = RegexFlags
70+
{ global: false
71+
, ignoreCase: false
72+
, multiline: false
73+
, sticky: false
74+
, unicode: true
75+
}
76+
77+
instance semigroupRegexFlags :: Semigroup RegexFlags where
78+
append (RegexFlags x) (RegexFlags y) = RegexFlags
79+
{ global: x.global || y.global
80+
, ignoreCase: x.ignoreCase || y.ignoreCase
81+
, multiline: x.multiline || y.multiline
82+
, sticky: x.sticky || y.sticky
83+
, unicode: x.unicode || y.unicode
84+
}
85+
86+
instance monoidRegexFlags :: Monoid RegexFlags where
87+
mempty = noFlags

test/Test/Data/String/Regex.purs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
module Test.Data.String.Regex (testStringRegex) where
22

3-
import Prelude (Unit, ($), bind, (==), not)
3+
import Prelude (Unit, ($), (<>), bind, (==), not)
44

55
import Control.Monad.Eff (Eff)
66
import Control.Monad.Eff.Console (CONSOLE, log)
77

88
import Data.Either (isLeft, fromRight)
99
import Data.Maybe (Maybe(..))
1010
import Data.String.Regex
11+
import Data.String.Regex.Flags (RegexFlags, global, ignoreCase, noFlags)
1112

1213
import Partial.Unsafe (unsafePartial)
1314

@@ -24,6 +25,11 @@ testStringRegex = do
2425
assert $ not (test (regex' "^b" noFlags) "abc")
2526
assert $ isLeft (regex "+" noFlags)
2627

28+
log "flags"
29+
assert $ "quxbarfoobaz" == replace (regex' "foo" noFlags) "qux" "foobarfoobaz"
30+
assert $ "quxbarquxbaz" == replace (regex' "foo" global) "qux" "foobarfoobaz"
31+
assert $ "quxbarquxbaz" == replace (regex' "foo" (global <> ignoreCase)) "qux" "foobarFOObaz"
32+
2733
log "match"
2834
assert $ match (regex' "^abc$" noFlags) "abc" == Just [Just "abc"]
2935

0 commit comments

Comments
 (0)