Skip to content

-split operator doesn't let you use options SingleLine and MultiLine at the same time (and it should) #4712

@HumanEquivalentUnit

Description

@HumanEquivalentUnit

Steps to reproduce

PS C:\> '' -split '', 0, 'singleline,multiline'
The combination of options with the -split operator is not valid.
    + CategoryInfo          : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : InvalidSplitOptionCombination

But 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


d78d

The 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Issue-Enhancementthe issue is more of a feature request than a bugResolution-FixedThe issue is fixed.WG-Languageparser, language semantics

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions