Skip to content

Commit 959a6d4

Browse files
committed
Add Regex.Unescape Span overloads
1 parent 734a7f7 commit 959a6d4

File tree

4 files changed

+29
-10
lines changed

4 files changed

+29
-10
lines changed

src/System.Text.RegularExpressions/ref/System.Text.RegularExpressions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ protected void InitializeReferences() { }
207207
void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo si, System.Runtime.Serialization.StreamingContext context) { }
208208
public override string ToString() { throw null; }
209209
public static string Unescape(string str) { throw null; }
210+
public static int Unescape(ReadOnlySpan<char> str, Span<char> destination) { throw null; }
210211
protected bool UseOptionC() { throw null; }
211212
protected bool UseOptionR() { throw null; }
212213
protected internal static void ValidateMatchTimeout(System.TimeSpan matchTimeout) { }

src/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,17 @@ public static string Unescape(string str)
276276
if (str == null)
277277
throw new ArgumentNullException(nameof(str));
278278

279-
return RegexParser.Unescape(str);
279+
return RegexParser.Unescape(str.AsSpan(), Span<char>.Empty, false, out _);
280+
}
281+
282+
/// <summary>
283+
/// Unescapes any escaped characters in the input text.
284+
/// </summary>
285+
public static int Unescape(ReadOnlySpan<char> str, Span<char> destination)
286+
{
287+
RegexParser.Unescape(str, destination, true, out int charsWritten);
288+
289+
return charsWritten;
280290
}
281291

282292
/// <summary>

src/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexParser.cs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -159,36 +159,39 @@ public static string Escape(ReadOnlySpan<char> input, Span<char> destination, bo
159159
/*
160160
* Escapes all metacharacters (including (,),[,],{,},|,^,$,*,+,?,\, spaces and #)
161161
*/
162-
public static string Unescape(string input)
162+
public static string Unescape(ReadOnlySpan<char> input, Span<char> destination, bool targetSpan, out int charsWritten)
163163
{
164164
for (int i = 0; i < input.Length; i++)
165165
{
166166
if (input[i] == '\\')
167167
{
168-
StringBuilder sb = StringBuilderCache.Acquire();
169168
RegexParser p = new RegexParser(CultureInfo.InvariantCulture);
170-
int lastpos;
171-
p.SetPattern(input);
169+
p.SetPattern(input.ToString());
172170

173-
sb.Append(input, 0, i);
171+
Span<char> charInitSpan = stackalloc char[256];
172+
var vsb = new ValueStringBuilder(charInitSpan);
173+
174+
vsb.Append(input.Slice(0, i));
175+
int lastpos;
174176
do
175177
{
176178
i++;
177179
p.Textto(i);
178180
if (i < input.Length)
179-
sb.Append(p.ScanCharEscape());
181+
vsb.Append(p.ScanCharEscape());
180182
i = p.Textpos();
181183
lastpos = i;
182184
while (i < input.Length && input[i] != '\\')
183185
i++;
184-
sb.Append(input, lastpos, i - lastpos);
186+
vsb.Append(input.Slice(lastpos, i - lastpos));
185187
} while (i < input.Length);
186188

187-
return StringBuilderCache.GetStringAndRelease(sb);
189+
return vsb.CopyOutput(destination, false, targetSpan, out charsWritten);
188190
}
189191
}
190192

191-
return input;
193+
// If nothing to escape, return the input.
194+
return input.CopyInput(destination, targetSpan, out charsWritten);
192195
}
193196

194197
/*

src/System.Text.RegularExpressions/tests/Regex.EscapeUnescape.Tests.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ public void Escape_NullString_ThrowsArgumentNullException()
4141
public void Unescape(string str, string expected)
4242
{
4343
Assert.Equal(expected, Regex.Unescape(str));
44+
45+
// Use Escape(ReadOnlySpan, Span)
46+
Span<char> output = stackalloc char[255];
47+
int charsWritten = Regex.Unescape(str.AsSpan(), output);
48+
SpanTestHelpers.VerifySpan(expected, charsWritten, output);
4449
}
4550

4651
[Fact]

0 commit comments

Comments
 (0)