Ejemplo n.º 1
0
        /// <summary>
        /// Managed wrapper around the raw match API.
        /// <para>From the RE2 docs for the underlying function:
        /// Don't ask for more match information than you will use:
        /// runs much faster with nsubmatch == 1 than nsubmatch > 1, and
        /// runs even faster if nsubmatch == 0.
        /// Doesn't make sense to use nsubmatch > 1 + NumberOfCapturingGroups(),
        /// but will be handled correctly.
        /// </para>
        /// </summary>
        /// <param name="hayBytes">The string to match the pattern against</param>
        /// <param name="startByteIndex">The byte offset to start at</param>
        /// <param name="numCaptures">The number of match groups to return</param>
        /// <returns>An array of byte ranges for the captures</returns>
        private unsafe ByteRange[] RawMatch(
            ReadOnlySpan <byte> hayBytes, int startByteIndex, int numCaptures)
        {
            var captures = new Re2Ffi.cre2_string_t[numCaptures];

            fixed(byte *pinnedHayBytes = hayBytes)
            {
                // TODO: Support anchor as a parameter
                var matchResult = Re2Ffi.cre2_match(
                    RawHandle,
                    pinnedHayBytes, hayBytes.Length,
                    startByteIndex, hayBytes.Length,
                    Re2Ffi.cre2_anchor_t.CRE2_UNANCHORED,
                    captures, captures.Length);

                if (matchResult != 1)
                {
                    return(Array.Empty <ByteRange>());
                }

                // Convert the captured strings to array indices while we still
                // have the haystack pinned. We can't have the haystack move
                // between the `_match` and the conversion to byte ranges
                // otherwise the pointer arithmetic we do will be invalidated.
                return(StringsToRanges(captures, new IntPtr(pinnedHayBytes)));
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Checks if the pattern matches somewhere in the given
        /// <paramref name="haystack" />.
        /// </summary>
        /// <param name="haystack">The text to find the pattern in</param>
        /// <returns>True if the pattern matches, false otherwise.</returns>
        public unsafe bool IsMatch(ReadOnlySpan <byte> haystack)
        {
            var captures = Array.Empty <Re2Ffi.cre2_string_t>();

            fixed(byte *hayBytesPtr = haystack)
            {
                // TODO: Support anchor as a parameter
                var matchResult = Re2Ffi.cre2_match(
                    RawHandle,
                    hayBytesPtr, haystack.Length,
                    0, haystack.Length,
                    Re2Ffi.cre2_anchor_t.CRE2_UNANCHORED,
                    captures, 0);

                return(matchResult == 1);
            }
        }