Ejemplo n.º 1
0
        public static object match(object thisObj, VsaEngine engine, object regExp)
        {
            string       string_obj = Convert.ToString(thisObj);
            RegExpObject regex_obj  = Convert.ToRegExp(regExp);
            bool         global     = regex_obj.global;

            if (!global)
            {
                return(RegExpPrototype.exec(regex_obj, string_obj));
            }

            MatchCollection md        = regex_obj.regex.Matches(string_obj);
            uint            n         = (uint)md.Count;
            Match           lastMatch = md [(int)(n - 1)];

            regex_obj.lastIndex = lastMatch.Index + 1;
            RegExpConstructor.UpdateLastMatch(lastMatch, string_obj);

            ArrayObject result = new ArrayObject();

            result.length = n;
            for (uint i = 0; i < n; i++)
            {
                result.elems [i] = md [(int)i].Value;
            }

            return(result);
        }
Ejemplo n.º 2
0
        public static object exec(object thisObj, object input)
        {
            RegExpObject re  = Convert.ToRegExp(thisObj);
            string       str = null;

            if (input == null)
            {
                RegExpConstructor ctr = RegExpConstructor.Ctr;
                str = Convert.ToString(ctr.GetField("$_").GetValue("$_"));
            }
            else
            {
                str = Convert.ToString(input);
            }
            bool global    = re.global;
            int  lastIndex = global ? (int)((double)re.lastIndex) : 0;
            bool success   = lastIndex >= 0 && lastIndex <= str.Length;

            Match md = null;

            if (success)
            {
                md      = re.regex.Match(str, lastIndex);
                success = md.Success;
            }

            if (!success)
            {
                re.lastIndex = 0;
                return(DBNull.Value);
            }

            int index    = md.Index;
            int endIndex = index + md.Length;

            if (global)
            {
                re.lastIndex = endIndex;
            }
            RegExpConstructor.UpdateLastMatch(md, str);

            GroupCollection caps   = md.Groups;
            uint            len    = (uint)caps.Count;
            RegExpMatch     result = new RegExpMatch();

            result.AddField("index", index);
            result.AddField("input", input);
            result.length = len;
            for (uint j = 0; j < len; j++)
            {
                result.elems [j] = caps [(int)j].Value;
            }

            return(result);
        }
Ejemplo n.º 3
0
        public static ArrayObject split(object thisObj, VsaEngine engine,
                                        object separator, object limit)
        {
            string      string_obj = Convert.ToString(thisObj);
            int         length     = string_obj.Length;
            int         max_count  = (limit != null) ? Convert.ToInt32(limit) : -1;
            ArrayObject result     = new ArrayObject();

            if (separator == null)
            {
                result.length          = (uint)1;
                result.elems [(uint)0] = string_obj;
                return(result);
            }

            int  start_pos = 0;
            int  end_pos   = -1;
            int  match_len = 0;
            uint count     = 0;
            int  sep_len   = 0;

            if (!(separator is RegExpObject))
            {
                string sep_str = Convert.ToString(separator);
                sep_len = sep_str.Length;

                if (string_obj.Length == 0)
                {
                    if (sep_len > 0)
                    {
                        result.length          = (uint)1;
                        result.elems [(uint)0] = string_obj;
                    }

                    return(result);
                }

                while (end_pos != length && (max_count == -1 || count < max_count))
                {
                    end_pos = (length != 0) ? string_obj.IndexOf(sep_str, start_pos) : length;
                    if (end_pos == -1)
                    {
                        end_pos = length;
                    }
                    else if (sep_len == 0)
                    {
                        end_pos++;
                    }

                    match_len            = end_pos - start_pos;
                    result.elems [count] = string_obj.Substring(start_pos, match_len);

                    start_pos += match_len + sep_len;
                    count++;
                }

                result.length = count;
                return(result);
            }

            RegExpObject    sep_re = (RegExpObject)separator;
            MatchCollection md     = sep_re.regex.Matches(string_obj);
            uint            n      = (uint)md.Count;

            Match match = null;

            for (int i = 0; i < n; i++)
            {
                if (max_count != -1 && count >= max_count)
                {
                    break;
                }

                match     = md [i];
                sep_len   = match.Length;
                end_pos   = match.Index;
                match_len = end_pos - start_pos;

                //
                // The specification says that "ab".split(/a*/) is ["", "b"], but would
                // that would also mean that "abcdef".split(/./).length would not be 6.
                // I'm currently going with the Rhino behavior that seems to make more
                // sense.
                //
                if (!(end_pos == 0 && sep_len == 0))
                {
                    result.elems [count] = string_obj.Substring(start_pos, match_len);
                    count++;
                }

                bool first_cap = true;
                foreach (Capture cap in match.Groups)
                {
                    if (max_count != -1 && count >= max_count)
                    {
                        break;
                    }

                    if (first_cap)
                    {
                        first_cap = false;
                        continue;
                    }

                    result.elems [count] = cap.Value;
                    count++;
                }

                start_pos += match_len + sep_len;
            }

            if (n > 0 && (max_count == -1 || count < max_count))
            {
                sep_re.lastIndex = match.Index + match.Length;
                RegExpConstructor.UpdateLastMatch(match, string_obj);

                if (start_pos < length)
                {
                    result.elems [count] = string_obj.Substring(start_pos);
                    count++;
                }
            }
            else if (n == 0)
            {
                result.elems [(uint)0] = string_obj;
                count++;
            }

            result.length = count;
            return(result);
        }