Merge: nitrpg: minor enhancements
[nit.git] / lib / standard / string_search.nit
index c718c96..437341f 100644 (file)
@@ -85,6 +85,7 @@ interface Pattern
                return res
        end
 
+       # Is `self` in `s`?
        protected fun is_in(s: Text): Bool do return search_index_in(s, 0) != -1
 end
 
@@ -139,13 +140,10 @@ class BM_Pattern
                end
        end
 
-       # Compile a new motif
-       init(motif: String)
+       init
        do
-               _motif = motif
                _length = _motif.length
                _gs = new Array[Int].with_capacity(_length)
-               _bc_table = new ArrayMap[Char, Int]
                compute_gs
                compute_bc
        end
@@ -154,7 +152,7 @@ class BM_Pattern
        private var motif: String
 
        # length of the motif
-       private var length: Int
+       private var length: Int is noinit
 
        private fun bc(e: Char): Int
        do
@@ -166,10 +164,10 @@ class BM_Pattern
        end
 
        # good shifts
-       private var gs: Array[Int]
+       private var gs: Array[Int] is noinit
        
        # bad characters
-       private var bc_table: Map[Char, Int]
+       private var bc_table = new ArrayMap[Char, Int]
 
        private fun compute_bc
        do
@@ -207,7 +205,6 @@ class BM_Pattern
 
        private fun compute_gs
        do
-               var x = _motif
                var m = _length
                var suff = suffixes
                var i = 0
@@ -255,15 +252,11 @@ class Match
        # The contents of the matching part
        redef fun to_s do return string.substring(from,length)
 
-       # Matches `len` characters of `s` from `f`.
-       init(s: String, f: Int, len: Int)
+       init
        do
-               assert positive_length: len >= 0
-               assert valid_from: f >= 0
-               assert valid_after: f + len <= s.length
-               string = s
-               from = f
-               length = len
+               assert positive_length: length >= 0
+               assert valid_from: from >= 0
+               assert valid_after: from + length <= string.length
        end
 end
 
@@ -337,6 +330,13 @@ redef class Text
        # Search the last occurence of the text `t`.
        #
        #     assert "bob".search_last("b").from == 2
+       #     assert "bob".search_last("bo").from == 0
+       #     assert "bob".search_last("ob").from == 1
+       #     assert "bobob".search_last("ob").from == 3
+       #     assert "bobbob".search_last("bb").from == 2
+       #     assert "bobbob".search_last("bob").from == 3
+       #     assert "bob".search_last("z") == null
+       #     assert "".search_last("b") == null
        fun search_last(t: Text): nullable Match do
                return search_last_up_to(t, length)
        end
@@ -370,16 +370,16 @@ redef class Text
        # Split `self` using `p` as separator.
        #
        #     assert "hello world".split('o')          ==  ["hell", " w", "rld"]
-       fun split(p: Pattern): Array[SELFTYPE]
+       fun split(p: Pattern): Array[String]
        do
                var matches = p.split_in(self)
-               var res = new Array[SELFTYPE].with_capacity(matches.length)
+               var res = new Array[String].with_capacity(matches.length)
                for m in matches do res.add(m.to_s)
                return res
        end
 
        # @deprecated alias for `split`
-       fun split_with(p: Pattern): Array[SELFTYPE] do return self.split(p)
+       fun split_with(p: Pattern): Array[String] do return self.split(p)
 
        # Split `self` on the first `=`
        #
@@ -388,15 +388,21 @@ redef class Text
        fun split_once_on(p: Pattern): Array[SELFTYPE]
        do
                var m = p.search_in(self, 0)
-               if m == null then return [self]
-               return new Array[SELFTYPE].with_items(substring(0, m.from), substring_from(m.after))
+               var res = new Array[SELFTYPE]
+               if m == null then
+                       res.add self
+               else
+                       res.add substring(0, m.from)
+                       res.add substring_from(m.after)
+               end
+               return res
        end
 
        # Replace all occurences of a pattern with a string
        #
        #     assert "hlelo".replace("le", "el")             ==  "hello"
        #     assert "hello".replace('l', "")        ==  "heo"
-       fun replace(p: Pattern, string: SELFTYPE): SELFTYPE
+       fun replace(p: Pattern, string: SELFTYPE): String
        do
                return self.split_with(p).join(string)
        end