예제 #1
0
        public static PhpArray preg_grep(Context ctx, string pattern, PhpArray input, int flags = 0)
        {
            if (input == null)
            {
                return(null);
            }

            var result = new PhpArray(input.Count);

            if (input.Count != 0)
            {
                var regex = new PerlRegex.Regex(pattern);

                var enumerator = input.GetFastEnumerator();
                while (enumerator.MoveNext())
                {
                    var str = enumerator.CurrentValue.ToStringOrThrow(ctx);
                    var m   = regex.Match(str);

                    // move a copy to return array if success and not invert or
                    // not success and invert
                    if (m.Success ^ (flags & PREG_GREP_INVERT) != 0)
                    {
                        result.Add(enumerator.CurrentKey, enumerator.CurrentValue.DeepCopy());
                    }
                }
            }

            //
            return(result);
        }
예제 #2
0
            protected override int Count(int countPatternIndex, string sequences)
            {
                var r     = new PcreRegex.Regex(PcreCountPatterns[countPatternIndex]);
                int count = 0;

                for (var m = r.Match(sequences); m.Success; m = m.NextMatch())
                {
                    count++;
                }

                return(count);
            }
예제 #3
0
        public static PhpArray preg_split(string pattern, string subject, int limit = -1, int flags = 0)
        {
            if (limit == 0) // 0 does not make sense, php's behavior is as it is -1
            {
                limit = -1;
            }
            if (limit < -1) // for all other negative values it seems that is as limit == 1
            {
                limit = 1;
            }

            if (string.IsNullOrEmpty(pattern))
            {
                return(null); // FALSE
            }

            if (subject == null)
            {
                subject = string.Empty;
            }

            var regex = new PerlRegex.Regex(pattern);

            //if (!regex.IsValid) return null;

            var m = regex.Match(subject);

            bool offset_capture = (flags & PREG_SPLIT_OFFSET_CAPTURE) != 0;
            var  result         = new PhpArray();
            int  last_index     = 0;

            while (m.Success && (limit == -1 || --limit > 0) && last_index < subject.Length)
            {
                // add part before match
                int length = m.Index - last_index;
                if (length > 0 || (flags & PREG_SPLIT_NO_EMPTY) == 0)
                {
                    result.Add(NewArrayItem(subject.Substring(last_index, length), last_index, offset_capture));
                }

                if (m.Value.Length > 0)
                {
                    if ((flags & PREG_SPLIT_DELIM_CAPTURE) != 0)    // add all captures but not whole pattern match (start at 1)
                    {
                        List <object> lastUnsucessfulGroups = null; // value of groups that was not successful since last succesful one
                        for (int i = 1; i < m.Groups.Count; i++)
                        {
                            var g = m.Groups[i];
                            if (g.Length > 0 || (flags & PREG_SPLIT_NO_EMPTY) == 0)
                            {
                                // the value to be added into the result:
                                object value = NewArrayItem(g.Value, g.Index, offset_capture);

                                if (g.Success)
                                {
                                    // group {i} was matched:
                                    // if there was some unsuccesfull matches before, add them now:
                                    if (lastUnsucessfulGroups != null && lastUnsucessfulGroups.Count > 0)
                                    {
                                        foreach (var x in lastUnsucessfulGroups)
                                        {
                                            result.Add(x);
                                        }
                                        lastUnsucessfulGroups.Clear();
                                    }
                                    // add the matched group:
                                    result.Add(value);
                                }
                                else
                                {
                                    // The match was unsuccesful, remember all the unsuccesful matches
                                    // and add them only if some succesful match will follow.
                                    // In PHP, unsuccessfully matched groups are trimmed by the end
                                    // (regexp processing stops when other groups cannot be matched):
                                    if (lastUnsucessfulGroups == null)
                                    {
                                        lastUnsucessfulGroups = new List <object>();
                                    }
                                    lastUnsucessfulGroups.Add(value);
                                }
                            }
                        }
                    }

                    last_index = m.Index + m.Length;
                }
                else // regular expression match an empty string => add one character
                {
                    // always not empty
                    result.Add(NewArrayItem(subject.Substring(last_index, 1), last_index, offset_capture));
                    last_index++;
                }

                m = m.NextMatch();
            }

            // add remaining string (might be empty)
            if (last_index < subject.Length || (flags & PREG_SPLIT_NO_EMPTY) == 0)
            {
                result.Add(NewArrayItem(subject.Substring(last_index), last_index, offset_capture));
            }

            return(result);
        }
예제 #4
0
        /// <summary>
        /// Perform a regular expression match.
        /// </summary>
        static int Match(Context ctx, string pattern, string subject, out PhpArray matches, int flags, long offset, bool matchAll)
        {
            subject = subject ?? string.Empty;

            var regex = new PerlRegex.Regex(pattern);
            var m     = regex.Match(subject, (offset < subject.Length) ? (int)offset : subject.Length);

            if ((regex.Options & PerlRegex.RegexOptions.PCRE_ANCHORED) != 0 && m.Success && m.Index != offset)
            {
                matches = PhpArray.NewEmpty();
                return(-1);
            }

            if (m.Success)
            {
                if (!matchAll || (flags & PREG_PATTERN_ORDER) != 0)
                {
                    matches = new PhpArray(m.Groups.Count);
                }
                else
                {
                    matches = new PhpArray();
                }

                if (!matchAll)
                {
                    GroupsToPhpArray(m.PcreGroups, (flags & PREG_OFFSET_CAPTURE) != 0, matches);
                    return(1);
                }

                // store all other matches in PhpArray matches
                if ((flags & PREG_SET_ORDER) != 0) // cannot test PatternOrder, it is 0, SetOrder must be tested
                {
                    return(FillMatchesArrayAllSetOrder(regex, m, ref matches, (flags & PREG_OFFSET_CAPTURE) != 0));
                }
                else
                {
                    return(FillMatchesArrayAllPatternOrder(regex, m, ref matches, (flags & PREG_OFFSET_CAPTURE) != 0));
                }
            }

            // no match has been found
            if (matchAll && (flags & PREG_SET_ORDER) == 0)
            {
                // in that case PHP returns an array filled with empty arrays according to parentheses count
                matches = new PhpArray(m.Groups.Count);
                for (int i = 0; i < regex.GetGroupNumbers().Length; i++)
                {
                    AddGroupNameToResult(regex, matches, i, (ms, groupName) =>
                    {
                        ms[groupName] = (PhpValue) new PhpArray();
                    });

                    matches[i] = (PhpValue) new PhpArray();
                }
            }
            else
            {
                matches = PhpArray.NewEmpty(); // empty array
            }

            return(0);
        }
예제 #5
0
        public static int preg_match(Context ctx, string pattern, string subject)
        {
            var regex = new PerlRegex.Regex(pattern);

            return(regex.Match(subject ?? string.Empty).Success ? 1 : 0);
        }