-match, -notmatch, -replace, and -split operators have inconsistent case-sensitivity behavior
Votes from Connect: 5
Original Date Submitted: 2/4/2015 1:35:58 PM
Handle: David Wyatt
Site Name: PowerShell
Feedback ID: 1114651
Frequency: Always Happens
Regression: I do not know if this issue existed previously
One would expect -imatch to always be case-insensitive, and -cmatch to always be case sensitive. However, this is only true if you pass something other than a [regex] object on the right of the operator. Under those conditions, PowerShell builds a new regex object with the proper case sensitive setting. If you pass in a [regex] object, it just uses that object regardless of whether it matches the case sensitivity behavior of the operator.
The same is true of the -notmatch operator. The -replace operator is a bit funny; it has this same bug if you only pass in a pattern (allowing the behavior to replace text with a null string), but always constructs new regex objects if you pass in a list of arguments as the right operand.
-Split, on the other hand, always builds a new regex and works the way you would expect, except for one tricky case, when the pattern itself contains regex options which contradict (and override) the regex constructor. (as shown in the repro steps. This same behavior applies to the -match, -notmatch, and -replace operators when strings are passed rather than regex objects.)
Product Studio item created by Connect Synchronizer due to creation of feedback ID 1114651 (http://connect.microsoft.com/PowerShell/feedback/ViewFeedback.aspx?FeedbackID=1114651).
$string = 'one_test_two'
$regex = [regex]'TEST'
# Demonstrating passing in regex objects to -match and -replace operators (no options in pattern)
$string -imatch $regex # False
$string -ireplace $regex, 'Replaced' # 'one_test_two'
$regex = New-Object regex('TEST', [System.Text.RegularExpressions.RegexOptions]::IgnoreCase)
$string -cmatch $regex # True
$string -creplace $regex # 'one__two'
$string -creplace $regex, '' # 'one_test_two'
# Demonstrating passing strings to these operators, when the string pattern contains embedded regex options.
$string -imatch '(?-i)TEST' # False
$string -cmatch '(?i)TEST' # True
$string -ireplace '(?-i)TEST', 'Replaced' # 'one_test_two'
$string -creplace '(?i)TEST', 'Replaced' # 'one_Replaced_two'
$string -csplit '(?i)TEST' # splits into array
$string -isplit '(?-i)TEST' # does not split
-c* operators should always be case sensitive, and -i* operators should always be case insensitive, regardless of what types of objects or patterns the caller passed in. When constructing new regex objects for these operators, PowerShell should first parse for and strip out the case-sensitive regex option, if present, so it doesn't override the RegexOptions value passed into the constructor.
Internal BugId: 13218