Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
<TargetFramework>$(NetCoreAppCurrent)</TargetFramework>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DefineConstants>$(DefineConstants);SYSTEM_TEXT_REGULAREXPRESSIONS</DefineConstants>
<UseCompilerGeneratedDocXmlFile>false</UseCompilerGeneratedDocXmlFile>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,25 @@

namespace System.Text.RegularExpressions
{
/// <summary>
/// Represents the results from a single subexpression capture. The object represents
/// one substring for a single successful capture.
/// </summary>
/// <summary>Represents the results from a single successful subexpression capture.</summary>
/// <remarks>
/// <para>
/// A <see cref="Capture"/> object is immutable and has no public constructor. Instances are returned
/// through the <see cref="CaptureCollection"/> object, which is returned by the
/// <see cref="Group.Captures"/> property. However, the <c>Match.Captures</c> property provides
/// information about the same match as the
/// <see cref="Match"/> object.
/// </para>
/// <para>
/// If you do not apply a quantifier to a capturing group, the <see cref="Group.Captures"/>
/// property returns a <see cref="CaptureCollection"/> with a single <see cref="Capture"/> object
/// that provides information about the same capture as the <see cref="Group"/> object. If you do
/// apply a quantifier to a capturing group, the <c>Group.Index</c>, <c>Group.Length</c>, and
/// <c>Group.Value</c> properties provide information only about the last captured group, whereas
/// the <see cref="Capture"/> objects in the <see cref="CaptureCollection"/> provide information
/// about all subexpression captures.
/// </para>
/// </remarks>
public class Capture
{
internal Capture(string? text, int index, int length)
Expand All @@ -16,24 +31,41 @@ internal Capture(string? text, int index, int length)
Length = length;
}

/// <summary>Returns the position in the original string where the first character of captured substring was found.</summary>
/// <summary>
/// Gets the position in the original string where the first character of the captured substring is found.
/// </summary>
/// <value>The zero-based starting position in the original string where the captured substring is found.</value>
public int Index { get; private protected set; }

/// <summary>Returns the length of the captured substring.</summary>
/// <summary>Gets the length of the captured substring.</summary>
/// <value>The length of the captured substring.</value>
public int Length { get; private protected set; }

/// <summary>The original string</summary>
internal string? Text { get; set; }

/// <summary>Gets the captured substring from the input string.</summary>
/// <value>The substring that is captured by the match.</value>
/// <remarks>
/// If a call to the <see cref="Regex.Match(string)"/> or <see cref="Match.NextMatch"/> method fails to
/// find a match, the value of the returned <c>Match.Value</c> property is <see cref="string.Empty"/>.
/// If the regular expression engine is unable to match a capturing group, the value of the returned
/// <c>Group.Value</c> property is <see cref="string.Empty"/>.
/// </remarks>
public string Value => Text is string text ? text.Substring(Index, Length) : string.Empty;

/// <summary>Gets the captured span from the input string.</summary>
/// <value>The span that is captured by the match.</value>
public ReadOnlySpan<char> ValueSpan => Text is string text ? text.AsSpan(Index, Length) : [];

/// <summary>Returns the substring that was matched.</summary>
/// <summary>
/// Retrieves the captured substring from the input string by calling the
/// <see cref="Value"/> property.
/// </summary>
/// <returns>The substring that was captured by the match.</returns>
/// <remarks>
/// <c>ToString</c> is actually an internal call to the <see cref="Value"/> property.
/// </remarks>
public override string ToString() => Value;

/// <summary>The substring to the left of the capture</summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,37 @@
namespace System.Text.RegularExpressions
{
/// <summary>
/// Represents a sequence of capture substrings. The object is used
/// to return the set of captures done by a single capturing group.
/// Represents the set of captures made by a single capturing group. The collection is immutable
/// (read-only) and has no public constructor.
/// </summary>
/// <remarks>
/// <para>
/// The <see cref="CaptureCollection" /> object contains one or more <see cref="Capture" /> objects.
/// Instances of the <see cref="CaptureCollection" /> class are returned by the following properties:
/// </para>
/// <list type="bullet">
/// <item>
/// The <see cref="Group.Captures" /> property. Each member of the collection represents a substring
/// captured by a capturing group. If a quantifier is not applied to a capturing group, the
/// <see cref="CaptureCollection" /> includes a single <see cref="Capture" /> object that represents
/// the same captured substring as the <see cref="Group" /> object. If a quantifier is applied to a
/// capturing group, the <see cref="CaptureCollection" /> includes one <see cref="Capture" /> object
/// for each captured substring, and the <see cref="Group" /> object provides information only about
/// the last captured substring.
/// </item>
/// <item>
/// The <c>Match.Captures</c> property. In this case, the collection consists of a single
/// <see cref="Capture" /> object that provides information about the match as a whole. That is, the
/// <see cref="CaptureCollection" /> object provides the same information as the <see cref="Match" />
/// object.
/// </item>
/// </list>
/// <para>
/// To iterate through the members of the collection, you should use the collection iteration construct
/// provided by your language (such as <c>foreach</c> in C#) instead of retrieving the enumerator that
/// is returned by the <see cref="GetEnumerator" /> method.
/// </para>
/// </remarks>
[DebuggerDisplay("Count = {Count}")]
[DebuggerTypeProxy(typeof(CollectionDebuggerProxy<Capture>))]
public class CaptureCollection : IList<Capture>, IReadOnlyList<Capture>, IList
Expand All @@ -25,15 +53,34 @@ internal CaptureCollection(Group group)
_capcount = _group._capcount;
}

/// <summary>Gets a value that indicates whether the collection is read only.</summary>
/// <value><see langword="true" /> in all cases.</value>
public bool IsReadOnly => true;

/// <summary>Returns the number of captures.</summary>
/// <summary>Gets the number of substrings captured by the group.</summary>
/// <value>The number of items in the <see cref="CaptureCollection" />.</value>
public int Count => _capcount;

/// <summary>Returns a specific capture, by index, in this collection.</summary>
/// <summary>Gets an individual member of the collection.</summary>
/// <param name="i">The index into the capture collection.</param>
/// <value>The captured substring at position <paramref name="i" /> in the collection.</value>
/// <exception cref="ArgumentOutOfRangeException">
/// <paramref name="i" /> is less than 0 or greater than or equal to
/// <see cref="Count" />.
/// </exception>
public Capture this[int i] => GetCapture(i);

/// <summary>Provides an enumerator in the same order as Item[].</summary>
/// <summary>Provides an enumerator that iterates through the collection.</summary>
/// <returns>
/// An object that contains all <see cref="Capture" /> objects within the
/// <see cref="CaptureCollection" />.
/// </returns>
/// <remarks>
/// Instead of calling the <see cref="GetEnumerator" /> method to retrieve an enumerator that lets
/// you iterate through the <see cref="Capture" /> objects in the collection, you should use the
/// collection iteration construct provided by your programming language (such as <c>foreach</c>
/// in C#).
/// </remarks>
public IEnumerator GetEnumerator() => new Enumerator(this);

IEnumerator<Capture> IEnumerable<Capture>.GetEnumerator() => new Enumerator(this);
Expand Down Expand Up @@ -73,10 +120,30 @@ internal void ForceInitialized()
}
}

/// <summary>
/// Gets a value that indicates whether access to the collection is synchronized (thread-safe).
/// </summary>
/// <value><see langword="false" /> in all cases.</value>
public bool IsSynchronized => false;

/// <summary>Gets an object that can be used to synchronize access to the collection.</summary>
/// <value>An object that can be used to synchronize access to the collection.</value>
public object SyncRoot => _group;

/// <summary>
/// Copies all the elements of the collection to the given array beginning at the given index.
/// </summary>
/// <param name="array">The array the collection is to be copied into.</param>
/// <param name="arrayIndex">The position in the destination array where copying is to begin.</param>
/// <exception cref="ArgumentNullException">
/// <paramref name="array" /> is <see langword="null" />.
/// </exception>
/// <exception cref="ArgumentException">
/// <paramref name="array" /> is multidimensional.
/// </exception>
/// <exception cref="IndexOutOfRangeException">
/// <paramref name="arrayIndex" /> is outside the bounds of <paramref name="array" />.
/// </exception>
public void CopyTo(Array array, int arrayIndex)
{
if (array is null)
Expand All @@ -90,6 +157,27 @@ public void CopyTo(Array array, int arrayIndex)
}
}

/// <summary>
/// Copies the elements of the collection to an <see cref="Array" />, starting at a particular
/// <see cref="Array" /> index.
/// </summary>
/// <param name="array">
/// The one-dimensional <see cref="Array" /> that is the destination of the elements copied from
/// the collection. The <see cref="Array" /> must have zero-based indexing.
/// </param>
/// <param name="arrayIndex">
/// The zero-based index in <paramref name="array" /> at which copying begins.
/// </param>
/// <exception cref="ArgumentNullException">
/// <paramref name="array" /> is <see langword="null" />.
/// </exception>
/// <exception cref="ArgumentOutOfRangeException">
/// <paramref name="arrayIndex" /> is less than 0.
/// </exception>
/// <exception cref="ArgumentException">
/// The number of elements in the source collection is greater than the available space from
/// <paramref name="arrayIndex" /> to the end of the destination <paramref name="array" />.
/// </exception>
public void CopyTo(Capture[] array, int arrayIndex)
{
if (array is null)
Expand Down
Loading
Loading