diff --git a/src/System.Management.Automation/engine/regex.cs b/src/System.Management.Automation/engine/regex.cs
index d69f3bdb88f..6e0ef9741d6 100644
--- a/src/System.Management.Automation/engine/regex.cs
+++ b/src/System.Management.Automation/engine/regex.cs
@@ -73,18 +73,6 @@ public sealed class WildcardPattern
// Default is WildcardOptions.None.
internal WildcardOptions Options { get; }
- ///
- /// Wildcard pattern converted to regex pattern.
- ///
- internal string PatternConvertedToRegex
- {
- get
- {
- var patternRegex = WildcardPatternToRegexParser.Parse(this);
- return patternRegex.ToString();
- }
- }
-
///
/// Initializes and instance of the WildcardPattern class
/// for the specified wildcard pattern.
@@ -205,6 +193,35 @@ public bool IsMatch(string input)
return input != null && _isMatch(input);
}
+ ///
+ /// Converts the wildcard pattern to its regular expression equivalent.
+ ///
+ ///
+ /// A object that represents the regular expression equivalent of the wildcard pattern.
+ /// The regex is configured with options matching the wildcard pattern's options.
+ ///
+ ///
+ /// This method converts a wildcard pattern to a regular expression.
+ /// The conversion follows these rules:
+ ///
+ /// - * (asterisk) converts to .* (matches any string)
+ /// - ? (question mark) converts to . (matches any single character)
+ /// - [abc] (bracket expression) converts to [abc] (matches any character in the set)
+ /// - Literal characters are escaped as needed for regex
+ ///
+ ///
+ ///
+ ///
+ /// var pattern = new WildcardPattern("*.txt");
+ /// Regex regex = pattern.ToRegex();
+ /// // regex.ToString() returns: "\.txt$"
+ ///
+ ///
+ public Regex ToRegex()
+ {
+ return WildcardPatternToRegexParser.Parse(this);
+ }
+
///
/// Escape special chars, except for those specified in , in a string by replacing them with their escape codes.
///
diff --git a/test/powershell/engine/WildcardPattern.Tests.ps1 b/test/powershell/engine/WildcardPattern.Tests.ps1
new file mode 100644
index 00000000000..81ced10f253
--- /dev/null
+++ b/test/powershell/engine/WildcardPattern.Tests.ps1
@@ -0,0 +1,77 @@
+# Copyright (c) Microsoft Corporation.
+# Licensed under the MIT License.
+
+Describe "WildcardPattern.ToRegex Tests" -Tags "CI" {
+ It "Converts '' to regex pattern ''" -TestCases @(
+ @{ Pattern = '*.txt'; Expected = '\.txt$' }
+ @{ Pattern = 'test?.log'; Expected = '^test.\.log$' }
+ @{ Pattern = 'file[0-9].txt'; Expected = '^file[0-9]\.txt$' }
+ @{ Pattern = 'test.log'; Expected = '^test\.log$' }
+ @{ Pattern = '*test*file*.txt'; Expected = 'test.*file.*\.txt$' }
+ @{ Pattern = 'file[0-9][a-z].txt'; Expected = '^file[0-9][a-z]\.txt$' }
+ @{ Pattern = 'test*'; Expected = '^test' }
+ @{ Pattern = '*test*'; Expected = 'test' }
+ ) {
+ param($Pattern, $Expected)
+ $wildcardPattern = [System.Management.Automation.WildcardPattern]::new($Pattern)
+ $regex = $wildcardPattern.ToRegex()
+ $regex | Should -BeOfType ([regex])
+ $regex.ToString() | Should -BeExactly $Expected
+ }
+
+ It "Converts '' with option" -TestCases @(
+ @{ Pattern = 'TEST'; OptionName = 'IgnoreCase'; Option = [System.Management.Automation.WildcardOptions]::IgnoreCase; Expected = '^TEST$'; ExpectedRegexOptions = 'IgnoreCase, Singleline'; TestString = 'test'; ExpectedMatch = $true }
+ @{ Pattern = 'test'; OptionName = 'CultureInvariant'; Option = [System.Management.Automation.WildcardOptions]::CultureInvariant; Expected = '^test$'; ExpectedRegexOptions = 'Singleline, CultureInvariant'; TestString = 'test'; ExpectedMatch = $true }
+ @{ Pattern = 'test*'; OptionName = 'Compiled'; Option = [System.Management.Automation.WildcardOptions]::Compiled; Expected = '^test'; ExpectedRegexOptions = 'Compiled, Singleline'; TestString = 'testing'; ExpectedMatch = $true }
+ ) {
+ param($Pattern, $OptionName, $Option, $Expected, $ExpectedRegexOptions, $TestString, $ExpectedMatch)
+ $wildcardPattern = [System.Management.Automation.WildcardPattern]::new($Pattern, $Option)
+ $regex = $wildcardPattern.ToRegex()
+ $regex | Should -BeOfType ([regex])
+ $regex.ToString() | Should -BeExactly $Expected
+ $regex.Options.ToString() | Should -BeExactly $ExpectedRegexOptions
+ $regex.IsMatch($TestString) | Should -Be $ExpectedMatch
+ }
+
+ It "Regex from '' matches '': " -TestCases @(
+ @{ Pattern = '*test*file*.txt'; TestString = 'mytestmyfile123.txt'; ShouldMatch = $true }
+ @{ Pattern = 'file[0-9][a-z].txt'; TestString = 'file5a.txt'; ShouldMatch = $true }
+ @{ Pattern = 'file[0-9][a-z].txt'; TestString = 'file55.txt'; ShouldMatch = $false }
+ ) {
+ param($Pattern, $TestString, $ShouldMatch)
+ $regex = [System.Management.Automation.WildcardPattern]::new($Pattern).ToRegex()
+ $regex.IsMatch($TestString) | Should -Be $ShouldMatch
+ }
+
+ Context "Edge cases" {
+ It "Handles empty pattern" {
+ $pattern = [System.Management.Automation.WildcardPattern]::new("")
+ $regex = $pattern.ToRegex()
+ $regex | Should -BeOfType ([regex])
+ $regex.ToString() | Should -Be "^$"
+ }
+
+ It "Handles pattern with only asterisk" {
+ $pattern = [System.Management.Automation.WildcardPattern]::new("*")
+ $regex = $pattern.ToRegex()
+ $regex | Should -BeOfType ([regex])
+ $regex.ToString() | Should -BeExactly ""
+ $regex.IsMatch("anything") | Should -BeTrue
+ $regex.IsMatch("") | Should -BeTrue
+ }
+
+ It "Handles escaped '' wildcard character" -TestCases @(
+ @{ Char = '*'; Pattern = 'file`*.txt'; Expected = '^file\*\.txt$' }
+ @{ Char = '?'; Pattern = 'file`?.txt'; Expected = '^file\?\.txt$' }
+ @{ Char = '['; Pattern = 'file`[.txt'; Expected = '^file\[\.txt$' }
+ @{ Char = ']'; Pattern = 'file`].txt'; Expected = '^file]\.txt$' }
+ ) {
+ param($Char, $Pattern, $Expected)
+ $wildcardPattern = [System.Management.Automation.WildcardPattern]::new($Pattern)
+ $regex = $wildcardPattern.ToRegex()
+ $regex | Should -BeOfType ([regex])
+ $regex.ToString() | Should -BeExactly $Expected
+ }
+
+ }
+}