-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Description
Steps to reproduce
PS C:\> '' -split '', 0, 'singleline,multiline'
The combination of options with the -split operator is not valid.
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : InvalidSplitOptionCombinationBut it is not an invalid combination, they do different things, and it is common and useful to use them together.
The PowerShell spec v 3.0, section 7.8.4.5 "Binary split operator" says:
[an options string] must not contain both Multiline and Singleline.
Multiline: This mode recognizes the start and end of lines and strings. The default mode is Singleline.
Singleline is not the default of Multiline, they are not two sides of the same option. Multiline changes how the regex characters ^ and $ work with newlines in a string, and Singleline changes how the regex character . works with newlines in a string. It is valid to use both options to change both ^$ and . at the same time.
e.g.
$text = @'
a12a
b34b
c56c
d78d
'@
# The following split fails, because '^' only matches the start of the entire string,
# and 'b' is not at the start of the string:
$text -split '^b'
# Enable 'Multiline' mode and '^' now matches the start of each line in the string
# and this now succeeds:
$text -split '^b', $numSplits, 'multiline'
# The following split fails, because '.+' only matches to the end of the line, and never gets to 'c'
$text -split 'b.+c'
# Enable 'Singleline' mode and '.' now matches over newlines
# and this now succeeds:
$text -split 'b.+c', $numSplits, 'singleline'
# To combine them and match from "the b at the start of a line,
# over newlines and up to the last c" needs both singleline and multiline options.
# This fails and throws an exception:
$text -split '^b.+c', $numSplits, 'singleline, multiline'
# but you can turn both on at the same time using regex syntax:
# so it can and does work, if you work around PowerShell:
$text -split '(?ms)^b.+c'
# splits on the text b34b`nc56c
# and you can also do it with the options string passed to the [regex] accelerator:
# This works, too:
PS D:\> [regex]::Split($text, '^b.+c', 'singleline,multiline')
a12a
d78dThe documentation in Get-Help about_split is also incorrect:
-- Multiline: Multiline mode recognizes the start and end of lines and strings. Valid only with RegexMatch. Singleline is the default. -- Singleline: Singleline mode recognizes only the start and end of strings. Valid only with RegexMatch. Singleline is the default.
Expected behavior
Specifying an options string 'singleline,multiline' is valid, and enables both Singleline and Multiline mode.
The documentation is accurate.
Actual behavior
It throws an exception and misleadingly says they are invalid together.
The documentation is inaccurate in three senses - implying there is one option being set instead of two, implying Singleline is the opposite of Multiline, and stating Singleline "is the default" when Singleline itself is off by default.
Environment data
> $PSVersionTable
Name Value
---- -----
PSVersion 6.0.0-beta
PSEdition Core
GitCommitId v6.0.0-beta.6
OS Linux 2.6.32-042stab120.6 #1 SMP Thu Oct 27 16:59:03 MSK 2016
Platform Unix
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0