Skip to content

Commit

Permalink
Add regex match iterator
Browse files Browse the repository at this point in the history
  • Loading branch information
autodidaddict committed Jul 30, 2017
1 parent b1a5cf3 commit 3e8c2d0
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 0 deletions.
39 changes: 39 additions & 0 deletions packages/regex/_test.pony
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ actor Main is TestList
test(_TestApply)
test(_TestGroups)
test(_TestEq)
test(_TestMatchIter)
test(_TestIterEmpty)
test(_TestSplit)
test(_TestError)

Expand Down Expand Up @@ -61,6 +63,43 @@ class iso _TestEq is UnitTest
h.assert_true(r == "1234", """ \d+ =~ "1234" """)
h.assert_true(r != "asdf", """ \d+ !~ "asdf" """)

class iso _TestMatchIter is UnitTest
"""
Tests the match iterator
"""
fun name(): String => "regex/Regex.matches"

fun apply(h: TestHelper) ? =>
let r = Regex("([+-]?\\s*\\d+[dD]\\d+|[+-]?\\s*\\d+)")?
let matches = r.matches("9d6+4d20+30-5d5+12-60")

let m1 = matches.next()?
h.assert_eq[String](m1(0)?, "9d6")
let m2 = matches.next()?
h.assert_eq[String](m2(0)?, "+4d20")
let m3 = matches.next()?
h.assert_eq[String](m3(0)?, "+30")
let m4 = matches.next()?
h.assert_eq[String](m4(0)?, "-5d5")
let m5 = matches.next()?
h.assert_eq[String](m5(0)?, "+12")
let m6 = matches.next()?
h.assert_eq[String](m6(0)?, "-60")
h.assert_false(matches.has_next())

class iso _TestIterEmpty is UnitTest
"""
Tests the match iterator when the subject doesn't contain any matches
for the regular expression
"""
fun name(): String => "regex/Regex.matches/nomatch"

fun apply(h: TestHelper) ? =>
let r = Regex("([+-]?\\s*\\d+[dD]\\d+|[+-]?\\s*\\d+)")?
let matches = r.matches("nevergonnaletyoudown")

h.assert_false(matches.has_next())

class iso _TestSplit is UnitTest
"""
Tests split.
Expand Down
38 changes: 38 additions & 0 deletions packages/regex/match_iter.pony
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
class MatchIterator is Iterator[Match]
"""
MatchIterator allows for calling code to repeatedly perform the same match
against a subject string as an iterator. This lets callers repeat the match
until no more matches exist.
"""
let _regex: Regex box
let _subject: String
var _offset: USize = 0

new create(regex': Regex box, subject': String, offset': USize = 0) =>
"""
Creates a new Match Iterator from a regular expression and a subject
string
"""
_regex = regex'
_subject = consume subject'
_offset = offset'

fun has_next() : Bool =>
"""
Indicates whether there is another match available
"""
try
let m = _regex(_subject, _offset)?
true
else
false
end

fun ref next() : Match? =>
"""
Yields the next match to the regular expression or produces
an error if there is no match
"""
let m = _regex(_subject, _offset)?
_offset = m.end_pos() + 1
m
7 changes: 7 additions & 0 deletions packages/regex/regex.pony
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,13 @@ class Regex

_jit = jit and (@pcre2_jit_compile_8[I32](_pattern, U32(1)) == 0)

fun matches(subject: String): MatchIterator =>
"""
Creates a match iterator from the regular expression that will iterate
over the supplied subject returning matches
"""
MatchIterator(this, subject)

fun eq(subject: ByteSeq box): Bool =>
"""
Return true on a successful match, false otherwise.
Expand Down

0 comments on commit 3e8c2d0

Please sign in to comment.