module re
import text
+intrude import text::flat
import gc
import error
# It is recommanded to use the higher level API offered by the class `Regex`,
# but it can still be used for advanced purpose or in optimized code.
#
-# To use this class and other `private` entities of this module, use `intrude import standard::re`
+# To use this class and other `private` entities of this module, use `intrude import core::re`
private extern class NativeRegex `{ regex_t* `}
# Allocate a new `NativeRegex`, it must then be compiled using `regcomp` before calling `regexec`
new malloc `{ return malloc(sizeof(regex_t)); `}
# Ignore case when matching letters
var ignore_case = false is writable
- # Optimize `self` for `is_in` and `String::has`, but do not support searches
+ # Optimize `self` for `String::has` and `is_in`, but do not support searches
#
# If `true`, `self` cannont be used with `String::search_all`, `String::replace`
# or `String::split`.
- var optimize_is_in = false is writable
+ var optimize_has = false is writable
# Treat a newline in string as dividing string into multiple lines
#
var cflags = 0
if extended then cflags |= flag_extended
if ignore_case then cflags |= flag_icase
- if optimize_is_in then cflags |= flag_nosub
+ if optimize_has then cflags |= flag_nosub
if newline then cflags |= flag_newline
var native = self.native
abort
end
- # require: not optimize_is_in
+ # require: not optimize_has
#
# assert "l".to_re.search_index_in("hello world", 0) == 2
# assert "el+o".to_re.search_index_in("hello world", 0) == 1
# assert "z".to_re.search_index_in("hello world", 0) == -1
redef fun search_index_in(text, from)
do
- assert not optimize_is_in
+ assert not optimize_has
var comp_res = compile
assert comp_res == null else "Regex compilation failed with: {comp_res.message}\n".output
abort
end
- # require: not optimize_is_in
+ # require: not optimize_has
#
# assert "l".to_re.search_in("hello world", 0).from == 2
# assert "el+o".to_re.search_in("hello world", 0).from == 1
# assert "z".to_re.search_in("hello world", 0) == null
redef fun search_in(text, from)
do
- assert not optimize_is_in
+ assert not optimize_has
var comp_res = compile
assert comp_res == null else "Regex compilation failed with: {comp_res.message}\n".output
# Actually execute
text = text.to_s
- var cstr = text.substring_from(from).to_cstring
+ var sub = text.substring_from(from)
+ var cstr = sub.to_cstring
+ var bstr = new FlatString.full(cstr, sub.bytelen, 0, sub.bytelen - 1, text.length - from)
var eflags = gather_eflags
var native_match = self.native_match
# Found one?
if res == 0 then
+ var bso = bstr.byte_to_char_index(native_match.rm_so)
+ var ln = bstr.byte_to_char_index(native_match.rm_eo - native_match.rm_so - 1)
var match = new Match(text,
- from + native_match.rm_so,
- native_match.rm_eo - native_match.rm_so)
+ from + bso,
+ ln + 1)
# Add sub expressions
- for i in [1..nsub] do
+ for i in [1 .. nsub] do
+ bso = bstr.byte_to_char_index(native_match[i].rm_so)
+ ln = bstr.byte_to_char_index(native_match[i].rm_eo - native_match[i].rm_so - 1)
match.subs.add new Match( text,
- native_match[i].rm_so,
- native_match[i].rm_eo - native_match[i].rm_so)
+ bso ,
+ ln + 1)
end
return match
abort
end
- # require: not optimize_is_in
+ # require: not optimize_has
#
# assert "ab".to_re.search_all_in("abbab").join(", ") == "ab, ab"
# assert "b+".to_re.search_all_in("abbabaabbbbbcab").join(", ") == "bb, b, bbbbb, b"
redef fun search_all_in(text)
do
- assert not optimize_is_in
+ assert not optimize_has
var comp_res = compile
assert comp_res == null else "Regex compilation failed with: {comp_res.message}\n".output