示例#1
0
文件: pcre.cs 项目: windsOne/peachpie
        static PhpValue PregReplaceInternal(Context ctx, string pattern, string replacement, IPhpCallable callback, PhpValue subject, int limit, ref long count)
        {
            var regex = new PerlRegex.Regex(pattern);

            // callback
            PerlRegex.MatchEvaluator evaluator = null;
            if (callback != null)
            {
                evaluator = (match) =>
                {
                    var matches_arr = new PhpArray(0);
                    GroupsToPhpArray(match.PcreGroups, false, matches_arr);

                    return(callback
                           .Invoke(ctx, (PhpValue)matches_arr)
                           .ToStringOrThrow(ctx));
                };
            }

            // TODO: subject as a binary string would be corrupted after Replace - https://github.com/peachpiecompiler/peachpie/issues/178

            //
            var subject_array = subject.AsArray();

            if (subject_array == null)
            {
                return(PhpValue.Create(
                           evaluator == null
                        ? regex.Replace(subject.ToStringOrThrow(ctx), replacement, limit, ref count)
                        : regex.Replace(subject.ToStringOrThrow(ctx), evaluator, limit, ref count)));
            }
            else
            {
                var arr = new PhpArray(subject_array.Count);

                var enumerator = subject_array.GetFastEnumerator();
                while (enumerator.MoveNext())
                {
                    var newvalue = evaluator == null
                        ? regex.Replace(enumerator.CurrentValue.ToStringOrThrow(ctx), replacement, limit, ref count)
                        : regex.Replace(enumerator.CurrentValue.ToStringOrThrow(ctx), evaluator, limit, ref count);

                    // TODO: trick on how to quickly update values od enumerated array without hashing:
                    // enumerator.CurrentValue = PhpValue.Create(newvalue);

                    arr[enumerator.CurrentKey] = newvalue;
                }

                return(PhpValue.Create(arr));
            }
        }
示例#2
0
        static PhpValue PregReplaceInternal(Context ctx, string pattern, string replacement, IPhpCallable callback, PhpValue subject, int limit, ref long count)
        {
            var regex = new PerlRegex.Regex(pattern);

            // callback
            PerlRegex.MatchEvaluator evaluator = null;
            if (callback != null)
            {
                evaluator = (match) =>
                {
                    var matches_arr = new PhpArray();
                    GroupsToPhpArray(match.PcreGroups, false, matches_arr);

                    return(callback
                           .Invoke(ctx, (PhpValue)matches_arr)
                           .ToStringOrThrow(ctx));
                };
            }

            // TODO: subject as a binary string would be corrupted after Replace - https://github.com/peachpiecompiler/peachpie/issues/178

            //
            var subject_array = subject.AsArray();

            if (subject_array != null)
            {
                var arr = new PhpArray(subject_array.Count);

                var enumerator = subject_array.GetFastEnumerator();
                while (enumerator.MoveNext())
                {
                    var input    = enumerator.CurrentValue;
                    var oldvalue = input.ToStringOrThrow(ctx);
                    var oldcount = count;

                    var newvalue = evaluator == null
                        ? regex.Replace(oldvalue, replacement, limit, ref count)
                        : regex.Replace(oldvalue, evaluator, limit, ref count);

                    // - quick workaround for https://github.com/peachpiecompiler/peachpie/issues/178
                    // - use the original value if possible (mem perf.)

                    arr[enumerator.CurrentKey] = (oldcount == count)
                        ? (input.IsBinaryString(out var bstring) ? bstring.DeepCopy() : oldvalue)
                        : newvalue;
                }

                return(arr);
            }
            else
            {
                var oldvalue = subject.ToStringOrThrow(ctx);
                var oldcount = count;

                var newvalue = evaluator == null
                        ? regex.Replace(oldvalue, replacement, limit, ref count)
                        : regex.Replace(oldvalue, evaluator, limit, ref count);

                // - quick workaround for https://github.com/peachpiecompiler/peachpie/issues/178
                // - use the original value if possible (mem perf.)

                return((oldcount == count)
                    ? (subject.IsBinaryString(out var bstring) ? bstring.DeepCopy() : oldvalue)
                    : newvalue);
            }
        }