How to split string by multiple characters in MSBuild 4?
MSBuild 4.0 property functions cannot handle arrays (well basically), however when you do a
Split(`,`, `-`)
You are invoking the String.Split(params string[])
overload, which requires an array (even in C# the params
keyword will create an array behind the scene and do something like Split(new string[] { ',', '-' })
internally).
What you could do is the following:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
ToolsVersion="4.0">
<PropertyGroup>
<MasterVersion>1.1-SNAPSHOT</MasterVersion>
</PropertyGroup>
<ItemGroup>
<SplitVersion Include="$(MasterVersion.Replace(`-`, `.`).Split(`.`))" />
</ItemGroup>
<Target Name="Test">
<Message Importance="high" Text="@(SplitVersion)"/>
</Target>
</Project>
Or you could first create the (string) array to be passed to Split:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<MasterVersion>1.1-SNAPSHOT</MasterVersion>
<Delimiters>.;-</Delimiters>
<DelimitersArray>$(Delimiters.Split(`;`))</DelimitersArray>
</PropertyGroup>
<ItemGroup>
<SplitVersion Include="$(MasterVersion.Split($(DelimitersArray)))" />
</ItemGroup>
<Target Name="Test">
<Message Importance="high" Text="@(SplitVersion)"/>
</Target>
</Project>
Which is not really better in this case ;-)
Oh, and you might want to check out this MSDN blog entry for more useful information.
Update for a comment:
The "content" of
SplitVersion
is technically an "array of ITaskItem", yes. You would deal with it however you would deal with Items (of ItemGroups); including things like "batching", etc.You cannot really "access things by index" in msbuild project files. Expressions like
$(SplitVersion)[0]
or@(SplitVersion)[0]
or@(SplitVersion[0])
don't do what you'd think/like. If you really would to you could assign individual properties for "array elements" by "index".
Example:
<PropertyGroup>
<SplitVersion0>$(MasterVersion.Split($(DelimitersArray))[0])</SplitVersion0>
<SplitVersion1>$(MasterVersion.Split($(DelimitersArray))[1])</SplitVersion1>
<SplitVersion2>$(MasterVersion.Split($(DelimitersArray))[2])</SplitVersion2>
</PropertyGroup>
The array-indexing operator works here, because in this case you are still "in the context" of the .NET expression. Once that is assigned to a property (or item group) you cannot do that anymore.