如何在MSBuild 4中按多个字符拆分字符串?

12

我有一个名为MasterVersion的字符串:

1.1-SNAPSHOT

我需要按照 . 和 - 分割它,以便它变成一个名为 SplitVersionstring[] 数组,例如:

1
1
SNAPSHOT

我已经尝试了所有我能想到的方法,包括以下几种变化,但都没有成功:

<!-- doesn't work -->
<ItemGroup>
    <VersionDelimiters Include="." />
    <VersionDelimiters Include="-" />
    <SplitVersion Include="$(MasterVersion.Split(@VersionDelimiters))" />
</ItemGroup>

<!-- doesn't work either -->
<ItemGroup>
    <SplitVersion Include="$(MasterVersion.Split([`.`; `-`]))" />
</ItemGroup>

我错过/搞糟了哪些晦涩的MSBuild语法?
(注意:保留了原文中的html标签,但对于中文页面来说不太适用)
3个回答

18

MSBuild 4.0属性函数不能很好地处理数组,但当你执行

Split(`,`, `-`)

您正在调用 String.Split(params string[]) 这个重载方法,它需要一个数组作为参数(即使在C#中使用params关键字也会在幕后创建一个数组并类似于Split(new string[] { ',', '-' })这样的操作)。

您可以尝试以下方式:

<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>

或者您可以先创建要传递给 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>

在这种情况下,这并不是真的更好;-)

哦,你可能想查看这篇MSDN博客以获取更多有用信息。

更新一条评论:

  • SplitVersion的“内容”在技术上是一个“ITaskItem数组”,是的。 您将处理它与处理项目(项目组中的项目)的方式相同; 包括诸如“批处理”等内容。

  • 您无法在msbuild项目文件中真正地“按索引访问”内容。像$(SplitVersion)[0]@(SplitVersion)[0]@(SplitVersion[0])这样的表达式 不能做你认为/希望的事情。如果你真的想要,你可以通过“索引”为“数组元素”分配单独的属性。

示例:

<PropertyGroup>
  <SplitVersion0>$(MasterVersion.Split($(DelimitersArray))[0])</SplitVersion0>
  <SplitVersion1>$(MasterVersion.Split($(DelimitersArray))[1])</SplitVersion1>
  <SplitVersion2>$(MasterVersion.Split($(DelimitersArray))[2])</SplitVersion2>
</PropertyGroup>
在这种情况下,数组索引操作符起作用,因为此时您仍处于.NET表达式的“上下文”中。一旦将其分配给属性(或项组),就不能再这样做了。

完成后,SplitVersion 的内容是什么?它应该是一个 ITaskItem 数组,对吗?我如何逐个访问这些值,比如按索引? - Neil Barnwell

-1

也许

<ItemGroup>
    <SplitVersion Include="$(MasterVersion.Split('.','-'))" />
</ItemGroup>

(MSBuild 应该自动将其转换为数组)


error MSB4184: The expression ""1.1-SNAPSHOT".Split(., -)" cannot be evaluated. Input string was not in a correct format. - Ian Kemp

-2

你正在一个ItemGroup中使用这个表达式,ItemGroups用于收集构建所需的工件。我认为你要找的是PropertyGroup

类似这样的:

<PropertyGroup>
  <MasterVersion>1.1-SNAPSHOT</MasterVersion>
  <SplitVersion Include="$(MasterVersion.Split(`.`,`-`)" />
</PropertyGroup>

你应该记住,在 MSBuild 中,属性使用 $(美元符号)进行引用。项目使用 @(at 符号)进行引用。

根据 MasterVersion 组的不同,你需要将 $ 更改为 @。


这是无法解析的,因为属性上不能有“Include”属性。 - Ian Kemp
是的,没错。当你像这样使用它时,它应该可以工作:<SplitVersion>$(MasterVersioin.Split('.','-')</SplitVersion>。 - Thorsten Hans
1
不是这样的。首先,它缺少一个闭合的')',其次请参阅我的有关数组支持的答案。 - Christian.K

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接