From a6fbdd5639ae140769484955fac0cc65620a9637 Mon Sep 17 00:00:00 2001 From: Genevieve Warren <24882762+gewarren@users.noreply.github.com> Date: Thu, 4 Jun 2026 10:32:14 -0700 Subject: [PATCH 01/10] move remarks back from conceptual docs repo --- .../Regex/Match.Examples.cs | 23 +++++++ .../Text/RegularExpressions/Regex.Match.cs | 66 +++++++++++++++++-- 2 files changed, 84 insertions(+), 5 deletions(-) create mode 100644 src/libraries/System.Text.RegularExpressions/samples/System.Text.RegularExpressions/Regex/Match.Examples.cs diff --git a/src/libraries/System.Text.RegularExpressions/samples/System.Text.RegularExpressions/Regex/Match.Examples.cs b/src/libraries/System.Text.RegularExpressions/samples/System.Text.RegularExpressions/Regex/Match.Examples.cs new file mode 100644 index 00000000000000..77ce5766148b20 --- /dev/null +++ b/src/libraries/System.Text.RegularExpressions/samples/System.Text.RegularExpressions/Regex/Match.Examples.cs @@ -0,0 +1,23 @@ +using System; +using System.Text.RegularExpressions; + +namespace System.Text.RegularExpressions.Examples +{ + public class MatchExample + { + public static void Run() + { + #region Match + string input = "Zip code: 98052"; + var regex = new Regex(@"(?<=Zip code: )\d{5}"); + Match match = regex.Match(input, 5); + if (match.Success) + Console.WriteLine($"Match found: {match.Value}"); + + // This code prints the following output: + // + // Match found: 98052 + #endregion + } + } +} diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Match.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Match.cs index 210e8954e888b2..b38eed40d6bbeb 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Match.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Match.cs @@ -442,11 +442,67 @@ public Match Match(string input) /// is less than zero or greater than the length of . /// /// A time-out occurred. - /// - /// For more information about , see - /// - /// Supplemental API remarks for Regex.Match. - /// + /// method returns the first substring that matches a regular expression pattern, + /// starting at or after the `startat` character position, in an input string. The regular expression pattern for which the + /// method searches is defined by the call to one of the + /// class constructors. For information about the language elements used to build a regular expression pattern, + /// see [Regular Expression Language - Quick Reference](/dotnet/standard/base-types/regular-expression-language-quick-reference). + /// + /// ## The `startat` parameter + /// + /// You can optionally specify a starting position in the string by using the `startat` parameter. Any matches starting before `startat` in the string are ignored. + /// If you don't specify a starting position, the search begins at the default position, which is the left end of `input` in a left-to-right search, and the right end + /// of `input` in a right-to-left search. Despite starting at `startat`, the index of any returned match is relative to the start of the string. + /// + /// Although the regular expression engine doesn't return any match starting before `startat`, it doesn't ignore the string before `startat`. This means that assertions + /// such as [anchors](/dotnet/standard/base-types/anchors-in-regular-expressions) or [lookbehind assertions](/dotnet/standard/base-types/backtracking-in-regular-expressions#lookbehind-assertions) + /// still apply to the input as a whole. For example, the following code includes a pattern with a lookbehind assertion that's satisfied even though it occurs + /// before the `startat` index of 5 in the input string. + /// + /// [!code-csharp[](../../../../samples/System.Text.RegularExpressions/Regex/Match.Examples.cs#Match)] + /// + /// > [!TIP] + /// > - If a pattern starts with the `^` anchor but `startat` is greater than 0, no matches will ever be found in a single-line search since they are constrained by `^` to start at index 0. + /// > - The [`\G` anchor](/dotnet/standard/base-types/anchors-in-regular-expressions#contiguous-matches-g) is satisfied at `startat`. Because of this, if you want to restrict + /// a match so that it begins exactly at a particular character position in the string, anchor the regular expression with a `\G` on the left for a left-to-right pattern. + /// This restricts the match so it must start exactly at `startat` (or, when multiple matches are desired, so the matches are contiguous). + /// + /// ## Right-to-left searches + /// + /// A right-to-left search, that is, when the regular expression pattern is constructed with the + /// option, behaves in the following ways: + /// + /// - The scan moves in the opposite direction and the pattern is matched from back (right) to front (left). + /// - The default starting position is the right end of the input string. + /// - If `startat` is specified, the right-to-left scan begins at the character at `startat` - 1 (not `startat`). + /// - When the `\G` anchor is specified at the right end of a pattern, it restricts the (first) match to end exactly at `startat` - 1. + /// + /// For more information about right-to-left searches, see [Right-to-left mode](/dotnet/standard/base-types/regular-expression-options#right-to-left-mode). + /// + /// ## Determine whether a match is found + /// + /// You can determine whether the regular expression pattern has been found in the input string by checking the value of the returned + /// object's property. If a match is found, the returned object's + /// property contains the substring from `input` that matches the regular expression pattern. + /// If no match is found, its value is . + /// + /// ## First or multiple matches + /// + /// This method returns the first substring found at or after the `startat` character position in `input` that matches the regular expression pattern. + /// You can retrieve subsequent matches by repeatedly calling the returned object's + /// method. You can also retrieve all matches in a single method call by calling the + /// method. + /// + /// ## Time-out exceptions + /// + /// The exception is thrown if the execution time of the matching operation exceeds the time-out + /// interval specified by the + /// constructor. If you do not set a time-out interval when you call the constructor, the exception is thrown if the operation exceeds any time-out value established + /// for the application domain in which the object is created. If no time-out is defined in the + /// constructor call or in the application domain's properties, or if the time-out value is , + /// no exception is thrown. + /// ]]> public Match Match(string input, int startat) { if (input is null) From a7a0284e8b31e29cb80a5b1c599259c36e566911 Mon Sep 17 00:00:00 2001 From: Genevieve Warren <24882762+gewarren@users.noreply.github.com> Date: Thu, 4 Jun 2026 10:34:12 -0700 Subject: [PATCH 02/10] use full urls --- .../src/System/Text/RegularExpressions/Regex.Match.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Match.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Match.cs index b38eed40d6bbeb..79b6a146a2ce79 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Match.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Match.cs @@ -447,7 +447,7 @@ public Match Match(string input) /// starting at or after the `startat` character position, in an input string. The regular expression pattern for which the /// method searches is defined by the call to one of the /// class constructors. For information about the language elements used to build a regular expression pattern, - /// see [Regular Expression Language - Quick Reference](/dotnet/standard/base-types/regular-expression-language-quick-reference). + /// see [Regular Expression Language - Quick Reference](https://learn.microsoft.com/dotnet/standard/base-types/regular-expression-language-quick-reference). /// /// ## The `startat` parameter /// @@ -456,7 +456,7 @@ public Match Match(string input) /// of `input` in a right-to-left search. Despite starting at `startat`, the index of any returned match is relative to the start of the string. /// /// Although the regular expression engine doesn't return any match starting before `startat`, it doesn't ignore the string before `startat`. This means that assertions - /// such as [anchors](/dotnet/standard/base-types/anchors-in-regular-expressions) or [lookbehind assertions](/dotnet/standard/base-types/backtracking-in-regular-expressions#lookbehind-assertions) + /// such as [anchors](https://learn.microsoft.com/dotnet/standard/base-types/anchors-in-regular-expressions) or [lookbehind assertions](https://learn.microsoft.com/dotnet/standard/base-types/backtracking-in-regular-expressions#lookbehind-assertions) /// still apply to the input as a whole. For example, the following code includes a pattern with a lookbehind assertion that's satisfied even though it occurs /// before the `startat` index of 5 in the input string. /// @@ -464,7 +464,7 @@ public Match Match(string input) /// /// > [!TIP] /// > - If a pattern starts with the `^` anchor but `startat` is greater than 0, no matches will ever be found in a single-line search since they are constrained by `^` to start at index 0. - /// > - The [`\G` anchor](/dotnet/standard/base-types/anchors-in-regular-expressions#contiguous-matches-g) is satisfied at `startat`. Because of this, if you want to restrict + /// > - The [`\G` anchor](https://learn.microsoft.com/dotnet/standard/base-types/anchors-in-regular-expressions#contiguous-matches-g) is satisfied at `startat`. Because of this, if you want to restrict /// a match so that it begins exactly at a particular character position in the string, anchor the regular expression with a `\G` on the left for a left-to-right pattern. /// This restricts the match so it must start exactly at `startat` (or, when multiple matches are desired, so the matches are contiguous). /// @@ -478,7 +478,7 @@ public Match Match(string input) /// - If `startat` is specified, the right-to-left scan begins at the character at `startat` - 1 (not `startat`). /// - When the `\G` anchor is specified at the right end of a pattern, it restricts the (first) match to end exactly at `startat` - 1. /// - /// For more information about right-to-left searches, see [Right-to-left mode](/dotnet/standard/base-types/regular-expression-options#right-to-left-mode). + /// For more information about right-to-left searches, see [Right-to-left mode](https://learn.microsoft.com/dotnet/standard/base-types/regular-expression-options#right-to-left-mode). /// /// ## Determine whether a match is found /// From 167f5e619f86ddda8b73988c3c42b943d7aa6d34 Mon Sep 17 00:00:00 2001 From: Genevieve Warren <24882762+gewarren@users.noreply.github.com> Date: Thu, 4 Jun 2026 18:13:37 -0700 Subject: [PATCH 03/10] Apply suggestions from code review Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .../Regex/Match.Examples.cs | 3 +++ .../src/System/Text/RegularExpressions/Regex.Match.cs | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Text.RegularExpressions/samples/System.Text.RegularExpressions/Regex/Match.Examples.cs b/src/libraries/System.Text.RegularExpressions/samples/System.Text.RegularExpressions/Regex/Match.Examples.cs index 77ce5766148b20..82c8f3ea73a710 100644 --- a/src/libraries/System.Text.RegularExpressions/samples/System.Text.RegularExpressions/Regex/Match.Examples.cs +++ b/src/libraries/System.Text.RegularExpressions/samples/System.Text.RegularExpressions/Regex/Match.Examples.cs @@ -1,3 +1,6 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + using System; using System.Text.RegularExpressions; diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Match.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Match.cs index 79b6a146a2ce79..b2711d4fcecdf9 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Match.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Match.cs @@ -451,9 +451,9 @@ public Match Match(string input) /// /// ## The `startat` parameter /// - /// You can optionally specify a starting position in the string by using the `startat` parameter. Any matches starting before `startat` in the string are ignored. - /// If you don't specify a starting position, the search begins at the default position, which is the left end of `input` in a left-to-right search, and the right end - /// of `input` in a right-to-left search. Despite starting at `startat`, the index of any returned match is relative to the start of the string. + /// You can optionally specify a starting position in the string by using the `startat` parameter. In a left-to-right search, any matches that begin before `startat` in the string are ignored. + /// If you don't specify a starting position, the search begins at the default position, which is the left end of `input` in a left-to-right search, and the right end of `input` in a right-to-left search. + /// Despite starting the search at `startat`, the index of any returned match is relative to the start of the string. /// /// Although the regular expression engine doesn't return any match starting before `startat`, it doesn't ignore the string before `startat`. This means that assertions /// such as [anchors](https://learn.microsoft.com/dotnet/standard/base-types/anchors-in-regular-expressions) or [lookbehind assertions](https://learn.microsoft.com/dotnet/standard/base-types/backtracking-in-regular-expressions#lookbehind-assertions) @@ -489,7 +489,7 @@ public Match Match(string input) /// /// ## First or multiple matches /// - /// This method returns the first substring found at or after the `startat` character position in `input` that matches the regular expression pattern. + /// This method returns the first substring found by scanning `input` starting at the `startat` position (or, for right-to-left searches, at `startat` - 1) that matches the regular expression pattern. /// You can retrieve subsequent matches by repeatedly calling the returned object's /// method. You can also retrieve all matches in a single method call by calling the /// method. From 6cf4bc4ceeba039860b28154eeacc5fe48d1c185 Mon Sep 17 00:00:00 2001 From: Genevieve Warren <24882762+gewarren@users.noreply.github.com> Date: Wed, 10 Jun 2026 20:14:47 -0700 Subject: [PATCH 04/10] move file to tests directory --- .../Regex => tests/FunctionalTests}/Match.Examples.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) rename src/libraries/System.Text.RegularExpressions/{samples/System.Text.RegularExpressions/Regex => tests/FunctionalTests}/Match.Examples.cs (86%) diff --git a/src/libraries/System.Text.RegularExpressions/samples/System.Text.RegularExpressions/Regex/Match.Examples.cs b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Match.Examples.cs similarity index 86% rename from src/libraries/System.Text.RegularExpressions/samples/System.Text.RegularExpressions/Regex/Match.Examples.cs rename to src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Match.Examples.cs index 77ce5766148b20..2fbda417f05ed5 100644 --- a/src/libraries/System.Text.RegularExpressions/samples/System.Text.RegularExpressions/Regex/Match.Examples.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Match.Examples.cs @@ -3,9 +3,10 @@ namespace System.Text.RegularExpressions.Examples { - public class MatchExample + public class MatchExamples { - public static void Run() + [Fact] + public static void MatchZipCode() { #region Match string input = "Zip code: 98052"; From 546e759b5b4a528b0ae2f68225618d3985564e87 Mon Sep 17 00:00:00 2001 From: Genevieve Warren <24882762+gewarren@users.noreply.github.com> Date: Wed, 10 Jun 2026 20:18:13 -0700 Subject: [PATCH 05/10] Apply suggestion from @gewarren --- .../src/System/Text/RegularExpressions/Regex.Match.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Match.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Match.cs index b2711d4fcecdf9..ecbe2308cd32dc 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Match.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Match.cs @@ -460,7 +460,7 @@ public Match Match(string input) /// still apply to the input as a whole. For example, the following code includes a pattern with a lookbehind assertion that's satisfied even though it occurs /// before the `startat` index of 5 in the input string. /// - /// [!code-csharp[](../../../../samples/System.Text.RegularExpressions/Regex/Match.Examples.cs#Match)] + /// [!code-csharp[](../../../../tests/FunctionalTests/Match.Examples.cs#Match)] /// /// > [!TIP] /// > - If a pattern starts with the `^` anchor but `startat` is greater than 0, no matches will ever be found in a single-line search since they are constrained by `^` to start at index 0. From 389435e8218287fc078afcd0ad133da7ba4e67d6 Mon Sep 17 00:00:00 2001 From: Genevieve Warren <24882762+gewarren@users.noreply.github.com> Date: Wed, 10 Jun 2026 20:45:57 -0700 Subject: [PATCH 06/10] add to test project file --- .../src/System/Text/RegularExpressions/Regex.Match.cs | 2 +- .../{Match.Examples.cs => Regex.Match.Examples.cs} | 0 .../FunctionalTests/System.Text.RegularExpressions.Tests.csproj | 1 + 3 files changed, 2 insertions(+), 1 deletion(-) rename src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/{Match.Examples.cs => Regex.Match.Examples.cs} (100%) diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Match.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Match.cs index ecbe2308cd32dc..a5fb071e0e4743 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Match.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Match.cs @@ -460,7 +460,7 @@ public Match Match(string input) /// still apply to the input as a whole. For example, the following code includes a pattern with a lookbehind assertion that's satisfied even though it occurs /// before the `startat` index of 5 in the input string. /// - /// [!code-csharp[](../../../../tests/FunctionalTests/Match.Examples.cs#Match)] + /// [!code-csharp[](../../../../tests/FunctionalTests/Regex.Match.Examples.cs#Match)] /// /// > [!TIP] /// > - If a pattern starts with the `^` anchor but `startat` is greater than 0, no matches will ever be found in a single-line search since they are constrained by `^` to start at index 0. diff --git a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Match.Examples.cs b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Regex.Match.Examples.cs similarity index 100% rename from src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Match.Examples.cs rename to src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Regex.Match.Examples.cs diff --git a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/System.Text.RegularExpressions.Tests.csproj b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/System.Text.RegularExpressions.Tests.csproj index c2dcd1dad82e2d..ec3ad6fde0ea82 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/System.Text.RegularExpressions.Tests.csproj +++ b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/System.Text.RegularExpressions.Tests.csproj @@ -31,6 +31,7 @@ + From dce5560f471bfa06e8eae2bf061324a77a443c44 Mon Sep 17 00:00:00 2001 From: Genevieve Warren <24882762+gewarren@users.noreply.github.com> Date: Wed, 10 Jun 2026 20:51:20 -0700 Subject: [PATCH 07/10] add asserts --- .../tests/FunctionalTests/Regex.Match.Examples.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Regex.Match.Examples.cs b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Regex.Match.Examples.cs index 366ddc2190593a..3c391a7e50196c 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Regex.Match.Examples.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Regex.Match.Examples.cs @@ -3,6 +3,7 @@ using System; using System.Text.RegularExpressions; +using Xunit; namespace System.Text.RegularExpressions.Examples { @@ -22,6 +23,9 @@ public static void MatchZipCode() // // Match found: 98052 #endregion + + Assert.True(match.Success); + Assert.Equal("98052", match.Value); } } } From 857d61904071f01fb03a7d045b583c31c3f265f5 Mon Sep 17 00:00:00 2001 From: Genevieve Warren <24882762+gewarren@users.noreply.github.com> Date: Wed, 10 Jun 2026 20:59:09 -0700 Subject: [PATCH 08/10] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .../src/System/Text/RegularExpressions/Regex.Match.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Match.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Match.cs index a5fb071e0e4743..af123b5b0858e7 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Match.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Match.cs @@ -465,8 +465,8 @@ public Match Match(string input) /// > [!TIP] /// > - If a pattern starts with the `^` anchor but `startat` is greater than 0, no matches will ever be found in a single-line search since they are constrained by `^` to start at index 0. /// > - The [`\G` anchor](https://learn.microsoft.com/dotnet/standard/base-types/anchors-in-regular-expressions#contiguous-matches-g) is satisfied at `startat`. Because of this, if you want to restrict - /// a match so that it begins exactly at a particular character position in the string, anchor the regular expression with a `\G` on the left for a left-to-right pattern. - /// This restricts the match so it must start exactly at `startat` (or, when multiple matches are desired, so the matches are contiguous). + /// > a match so that it begins exactly at a particular character position in the string, anchor the regular expression with a `\G` on the left for a left-to-right pattern. + /// > This restricts the match so it must start exactly at `startat` (or, when multiple matches are desired, so the matches are contiguous). /// /// ## Right-to-left searches /// From 39b889f5f71ccd701cba02feb2cff97bd2027e7c Mon Sep 17 00:00:00 2001 From: Genevieve Warren <24882762+gewarren@users.noreply.github.com> Date: Wed, 10 Jun 2026 21:09:12 -0700 Subject: [PATCH 09/10] Apply suggestions from code review Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .../src/System/Text/RegularExpressions/Regex.Match.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Match.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Match.cs index af123b5b0858e7..fa81029ac701c3 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Match.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Match.cs @@ -451,8 +451,8 @@ public Match Match(string input) /// /// ## The `startat` parameter /// - /// You can optionally specify a starting position in the string by using the `startat` parameter. In a left-to-right search, any matches that begin before `startat` in the string are ignored. - /// If you don't specify a starting position, the search begins at the default position, which is the left end of `input` in a left-to-right search, and the right end of `input` in a right-to-left search. + /// Use the `startat` parameter to specify the character position at which the search starts. In a left-to-right search, any matches that begin before `startat` in the string are ignored. + /// To start at the default position, use the overload (or pass 0 for a left-to-right search and `input.Length` for a right-to-left search). /// Despite starting the search at `startat`, the index of any returned match is relative to the start of the string. /// /// Although the regular expression engine doesn't return any match starting before `startat`, it doesn't ignore the string before `startat`. This means that assertions @@ -463,7 +463,7 @@ public Match Match(string input) /// [!code-csharp[](../../../../tests/FunctionalTests/Regex.Match.Examples.cs#Match)] /// /// > [!TIP] - /// > - If a pattern starts with the `^` anchor but `startat` is greater than 0, no matches will ever be found in a single-line search since they are constrained by `^` to start at index 0. + /// > - If a pattern starts with the `^` anchor, `startat` is greater than 0, and the regular expression isn't using , no matches will ever be found since they are constrained by `^` to start at index 0. /// > - The [`\G` anchor](https://learn.microsoft.com/dotnet/standard/base-types/anchors-in-regular-expressions#contiguous-matches-g) is satisfied at `startat`. Because of this, if you want to restrict /// > a match so that it begins exactly at a particular character position in the string, anchor the regular expression with a `\G` on the left for a left-to-right pattern. /// > This restricts the match so it must start exactly at `startat` (or, when multiple matches are desired, so the matches are contiguous). From c6fd816adea7621a8d2c59d9e5f582342af0344a Mon Sep 17 00:00:00 2001 From: Genevieve Warren <24882762+gewarren@users.noreply.github.com> Date: Fri, 12 Jun 2026 08:30:15 -0700 Subject: [PATCH 10/10] respond to feedback --- .../adding-api-guidelines.md | 27 ++++++++++++++----- .../Text/RegularExpressions/Regex.Match.cs | 2 +- ...ex.Match.Examples.cs => Regex.Examples.cs} | 0 ...ystem.Text.RegularExpressions.Tests.csproj | 2 +- 4 files changed, 23 insertions(+), 8 deletions(-) rename src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/{Regex.Match.Examples.cs => Regex.Examples.cs} (100%) diff --git a/docs/coding-guidelines/adding-api-guidelines.md b/docs/coding-guidelines/adding-api-guidelines.md index a276c3af927b7e..0b1c8a5115200f 100644 --- a/docs/coding-guidelines/adding-api-guidelines.md +++ b/docs/coding-guidelines/adding-api-guidelines.md @@ -47,10 +47,6 @@ New public APIs must be documented with triple-slash comments on top of them. Vi [API writing guidelines](https://github.com/dotnet/dotnet-api-docs/wiki) has information about language and proper style for writing API documentation. If your new API or the APIs it calls throw any exceptions, those need to be manually documented by adding the `` elements. -After your change is merged, we will eventually port them to the [dotnet-api-docs](https://github.com/dotnet/dotnet-api-docs) repo. The tools used for this port live in [api-docs-sync](https://github.com/dotnet/api-docs-sync) repo. Once the dotnet-api-docs change -is merged, your comments will start showing up in the official API documentation at https://learn.microsoft.com, and later they'll appear in IntelliSense -in Visual Studio and Visual Studio Code. - The rest of the documentation workflow depends on whether the assembly has the `UseCompilerGeneratedDocXmlFile` property set in its project file: **For libraries without this property (or with it set to `true`, which is the default):** @@ -58,12 +54,31 @@ The rest of the documentation workflow depends on whether the assembly has the ` - Triple-slash comments in source code are synced to dotnet-api-docs periodically (every preview). - More recently introduced libraries typically follow this workflow. +**For libraries with this property set to `false`:** +- The docs in the [dotnet-api-docs](https://github.com/dotnet/dotnet-api-docs) repo are the source of truth for documentation. +- After your change is merged into the runtime repo, we will eventually port the docs to the dotnet-api-docs repo. The tools used for this port live in +the [api-docs-sync](https://github.com/dotnet/api-docs-sync) repo. Once the dotnet-api-docs change +is merged, your doc comments will appear in +the official API documentation at https://learn.microsoft.com, and later they'll appear in IntelliSense +in Visual Studio and Visual Studio Code. +- Older libraries typically follow this workflow. + +### API usage examples + +API usage examples are included in the test sources so they can be validated during regular test runs. These examples should either be placed in the `examples` subdirectory or use a filename with the `Examples` suffix. depending on what's the best fit for the test project structure. The specific code intended for the published documentation is marked with a #region directive, which allows test-related boilerplate (such as the [Fact] attribute) to be excluded from the final documentation. + +The API usage examples are referenced from the documentation using the code-csharp directive. For example: + +`[!code-csharp[](../../../../tests/System.Text.RegularExpressions/FunctionalTests/Regex.Examples.cs#Match)]` + +This directive pulls the code snippet identified by the specified `#region` from the source file and embeds it directly into the documentation. + ### Documentation placement in platform-specific libraries When a library targets platform-specific frameworks (e.g. `net11.0-windows`, `net11.0-linux`), only **one** platform's compiler-generated doc XML is selected as the source of truth and shipped to all customers in the IntelliSense package. This means that if XML doc comments for a public API -appear only in a platform-specific partial file, they may be missing from the shipped docs on other +appear only in a platform-specific partial file, they might be missing from the shipped docs on other platforms. To ensure consistent documentation across all platforms, follow these rules: @@ -106,7 +121,7 @@ established `TypeNameAsync.cs` pattern), suppress the specific diagnostic with updates must be made directly in the dotnet-api-docs repo. - It's fine to make updates to the triple-slash comments later to aid local development, they just won't automatically flow into the official docs. Copilot can help with porting small changes in triple-slash comments to dotnet-api-docs. [PortToDocs](https://github.com/dotnet/api-docs-sync/blob/main/docs/PortToDocs.md) tool works better for ports of large changes. -- Older libraries typically follow this workflow. Libraries in this mode can work towards a better workflow in the future by using api-docs-sync tools to port back docs to source, then removing the `UseCompilerGeneratedDocXmlFile` property. +- Older libraries typically follow this workflow. Libraries in this mode can work towards a better workflow in the future by using api-docs-sync tools or an AI agent to port back docs to source, then removing the `UseCompilerGeneratedDocXmlFile` property. ## FAQ diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Match.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Match.cs index a5fb071e0e4743..bcb7369afaaf51 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Match.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Match.cs @@ -460,7 +460,7 @@ public Match Match(string input) /// still apply to the input as a whole. For example, the following code includes a pattern with a lookbehind assertion that's satisfied even though it occurs /// before the `startat` index of 5 in the input string. /// - /// [!code-csharp[](../../../../tests/FunctionalTests/Regex.Match.Examples.cs#Match)] + /// [!code-csharp[](../../../../tests/FunctionalTests/Regex.Examples.cs#Match)] /// /// > [!TIP] /// > - If a pattern starts with the `^` anchor but `startat` is greater than 0, no matches will ever be found in a single-line search since they are constrained by `^` to start at index 0. diff --git a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Regex.Match.Examples.cs b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Regex.Examples.cs similarity index 100% rename from src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Regex.Match.Examples.cs rename to src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Regex.Examples.cs diff --git a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/System.Text.RegularExpressions.Tests.csproj b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/System.Text.RegularExpressions.Tests.csproj index ec3ad6fde0ea82..ebebc0e8499453 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/System.Text.RegularExpressions.Tests.csproj +++ b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/System.Text.RegularExpressions.Tests.csproj @@ -28,10 +28,10 @@ + -