【问题标题】:Regex that is working in C# is not working in MSBuild在 C# 中工作的正则表达式在 MSBuild 中不起作用
【发布时间】:2019-11-28 19:40:51
【问题描述】:

我想验证使用dotnet build /p:VERSION=1.2.3GeneratePackageOnBuild 打包一些nuget 包时使用的版本。我的正则表达式正在使用 C# 在 LINQPad 6 中工作:

Regex.Match("1.2.3", @"^\d{1,3}\.\d{1,3}\.\d{1,6}(-(beta|rc)(\d{1,1})?)?$")

但是,在我的 default.props 中,所有 csproj 文件(使用新的 sdk 样式,如果相关的话)正在导入它,但我有这个,但它根本不工作:

<Target Name="ValidateVersion" BeforeTargets="BeforeBuild">
  <PropertyGroup>
    <VersionRegex>^\d{1,3}\.\d{1,3}\.\d{1,6}(-(beta|rc)(\d{1,1})?)?$</VersionRegex>
    <VersionTest>1.2.3</VersionTest> <!-- Just to make it easier during testing -->
  </PropertyGroup>

  <Error
    Text="Version is not following the correct format: $(VersionRegex)"
    Condition=" $([System.Text.RegularExpressions.Regex]::IsMatch('$(VersionTest)', `$(VersionRegex)`)) " />
</Target>

如果我内联VersionRegexVersionTest,它仍然无法正常工作。任何想法为什么它在 C# 中工作而不是在 MSBuild 中?

【问题讨论】:

  • 我在这个系统上一无所获(只是因为 C# 标签),但通常类型必须正确注释。而且那些看起来不像它们被正确地标记为字​​符串。下面的文本和条件字符串是如何注释的。
  • 可能是因为 xml 转义没有达到预期的效果。尝试将您的正则表达式粘贴在 CDATA 中。
  • @viethoang:在 XML 中只有 5 个字符需要转义/编码:&lt;&gt;&amp; 以及单引号(/撇号)和双引号.我没有看到任何这些
  • 没错,接下来的想法是将 IsMatch() 中的四个单引号替换为 "
  • @Christopher 听起来很有道理。如何将它们注释为字符串?我尝试将变量内联为 [System.String]'^\d{1,3}\.\d{1,3}\.\d{1,6}(-(beta|rc)(\d{1,1})?)?$' 并使用反引号,但我仍然得到相同的结果。

标签: c# regex .net-core msbuild csproj


【解决方案1】:

从您的原始示例中,您应该能够将VersionRegex 属性的内容放在CDATA 中:

<Target Name="ValidateVersion" BeforeTargets="BeforeBuild">
  <PropertyGroup>
    <VersionRegex><![CDATA[^\d{1,3}\.\d{1,3}\.\d{1,6}(-(beta|rc)(\d{1,1})?)?$]]></VersionRegex>
    <VersionTest>1.2.3</VersionTest>
  </PropertyGroup>

  <Error
    Text="Version is not following the correct format: $(VersionRegex)"
    Condition="!$([System.Text.RegularExpressions.Regex]::IsMatch('$(VersionTest)', '$(VersionRegex)'))" />
</Target>

【讨论】:

  • 谢谢,它似乎工作了!您可以在Condition 的开头添加! 吗?之后我会将您的答案标记为已接受。
  • 有趣的是,我可能会使用您的答案,因为我正在尝试使用命名匹配组,但 MSBuild 不允许我访问 $([System.Text.RegularExpressions.Regex]::Match($(VersionTest), $(VersionRegex)).Groups["my_group"]
  • 太好了,我的回答仍然对其他人有用!
【解决方案2】:

解决方法

我还没有找到实际问题,但解决方法是,如 @Viet Hoang mentioned in the comments,使用 CDATA:

Targets/ValidateVersioning.targets:

<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <UsingTask
    TaskName="ValidateVersion"
    TaskFactory="RoslynCodeTaskFactory"
    AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll" >
    <ParameterGroup>
      <Version ParameterType="System.String" Required="true" />
    </ParameterGroup>
    <Task>
      <Using Namespace="System"/>
      <Using Namespace="System.IO"/>
      <Using Namespace="System.Text.RegularExpressions"/>
      <Code Type="Fragment" Language="cs">
<![CDATA[
if (!Regex.Match(Version, @"^\d{1,3}\.\d{1,3}\.\d{1,6}(-(beta|rc)(\d{1,1})?)?$").Success)
{
    Log.LogError("Version has wrong format: {0}", Version);
    return false;
}
]]>
      </Code>
    </Task>
  </UsingTask>
</Project>

default.props:

<Project>

...

  <Import Project="Targets\ValidateVersioning.targets" />
  <Target Condition="$(VERSION) != ''" Name="ValidateVersion" BeforeTargets="BeforeBuild">
    <ValidateVersion Version="$(VERSION)" />
  </Target>

...

</Project>

&gt; dotnet build --no-restore -p:Version=1.3.4 可以,但是

&gt; dotnet build --no-restore -p:Version=1.3 不会构建

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-28
    • 1970-01-01
    • 2021-03-18
    • 2016-08-01
    相关资源
    最近更新 更多