Regex 什么';在AssemblyInfo.cs文件中更新程序集内部版本号的正则表达式?

Regex 什么';在AssemblyInfo.cs文件中更新程序集内部版本号的正则表达式?,regex,Regex,现在,我正在AssemblyInfo.cs文件中为替换程序集版本编写VS 2008宏。从MSDN中,必须使用以下模式编写程序集版本 大调.小调[建造[修订]] 示例 1.0 1.0.1234 1.0.1234.0 我需要动态生成'AssemblyInfo.cs'文件的内部版本号,并使用正则表达式将旧的内部版本号替换为新生成的内部版本号 你有解决这个问题的正则表达式吗?此外,构建编号不能包含在注释语句中,如下面的代码所示。最后,别忘了检查正则表达式中的内联注释 不要替换任何已注释的内部版本号

现在,我正在AssemblyInfo.cs文件中为替换程序集版本编写VS 2008宏。从MSDN中,必须使用以下模式编写程序集版本

大调.小调[建造[修订]]

示例

  • 1.0
  • 1.0.1234
  • 1.0.1234.0
我需要动态生成'AssemblyInfo.cs'文件的内部版本号,并使用正则表达式将旧的内部版本号替换为新生成的内部版本号

你有解决这个问题的正则表达式吗?此外,构建编号不能包含在注释语句中,如下面的代码所示。最后,别忘了检查正则表达式中的内联注释

不要替换任何已注释的内部版本号

//[assembly: AssemblyVersion("0.1.0.0")]

/*[assembly: AssemblyVersion("0.1.0.0")]*/

/*
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: AssemblyVersion("0.1.0.0")]
 */
替换未注释的内部版本号

[assembly: AssemblyVersion("0.1.0.0")] // inline comment
/* inline comment */ [assembly: AssemblyVersion("0.1.0.0")]
[assembly: /*inline comment*/AssemblyVersion("0.1.0.0")]
提示。


请在

尝试您的正则表达式这有点粗糙,但您可以执行以下操作

搜索:

^{\[assembly\: :w\(\"0\.1\.}\*
替换为:

\1####
其中#####是您的替换字符串

该正则表达式的工作如下:

  • 它首先搜索以\[assembly\:开头的行(^表示行的开头,反斜杠转义特殊字符),后跟
  • …某些字母标识符:w,后跟
  • …一个左括号(),后跟
  • …版本字符串的开头,用引号“0\.1\.,最后后跟
  • …星号\*
  • 步骤1-4使用大括号{}作为第一个标记表达式捕获
  • 替换字符串逐字删除标记的表达式,这样它就不会受到以下影响:\1,后跟替换字符串some###
  • 注释行将被忽略,因为它们不是以[assembly:]开头。后续的行内注释将保持不变,因为它们不会被正则表达式捕获


    如果这不完全是您所需要的,那么使用正则表达式来捕获和/或替换行的不同部分就相当简单了。

    这有点粗糙,但您可以执行以下操作

    搜索:

    ^{\[assembly\: :w\(\"0\.1\.}\*
    
    替换为:

    \1####
    
    其中#####是您的替换字符串

    该正则表达式的工作如下:

  • 它首先搜索以\[assembly\:开头的行(^表示行的开头,反斜杠转义特殊字符),后跟
  • …某些字母标识符:w,后跟
  • …一个左括号(),后跟
  • …版本字符串的开头,用引号“0\.1\.,最后后跟
  • …星号\*
  • 步骤1-4使用大括号{}作为第一个标记表达式捕获
  • 替换字符串逐字删除标记的表达式,这样它就不会受到以下影响:\1,后跟替换字符串some###
  • 注释行将被忽略,因为它们不是以[assembly:]开头。后续的行内注释将保持不变,因为它们不会被正则表达式捕获


    如果这不完全是您所需要的,那么使用正则表达式来捕获和/或替换行的不同部分是相当简单的。

    我怀疑使用正则表达式在这里会对您有多大好处。虽然可以制定一个与“未注释”匹配的表达式程序集版本属性将很难维护和理解

    您现在的语法对自己造成了很大的困难。在AssemblyInfo.cs文件上强制执行一个编码标准,规定行应该始终以开头注释掉//并禁止内联注释,这样做应该很容易使用StreamReader对其进行解析

    如果你做不到这一点,那么只有一个解析器可以保证处理你所有的边缘情况,那就是C#编译器。不如只编译你的程序集,然后反射它来检测版本号

    var asm = Assembly.LoadFile("foo.dll");
    var version = Assembly.GetExecutingAssembly().GetName().Version;
    

    如果你只是想增加你的版本号,你应该看看这个问题:

    我怀疑在这里使用正则表达式会对你有多大好处。虽然可以制定一个与“未注释”程序集版本属性匹配的表达式,但它很难维护和理解

    您现在的语法对自己造成了很大的困难。在AssemblyInfo.cs文件上强制执行一个编码标准,规定行应该始终以开头注释掉//并禁止内联注释,这样做应该很容易使用StreamReader对其进行解析

    如果你做不到这一点,那么只有一个解析器可以保证处理你所有的边缘情况,那就是C#编译器。不如只编译你的程序集,然后反射它来检测版本号

    var asm = Assembly.LoadFile("foo.dll");
    var version = Assembly.GetExecutingAssembly().GetName().Version;
    

    如果你只是想增加你的版本号,你应该看看这个问题:

    我刚刚找到了我问题的答案。但是答案非常复杂&非常长的正则表达式。顺便说一句,我每个解决方案只使用这个语法一次。所以,它不会影响整体性能。请看我完整的源代码

    模块环境事件.vb

    Public Module EnvironmentEvents
        Private Sub BuildEvents_OnBuildBegin(ByVal Scope As EnvDTE.vsBuildScope, ByVal Action As EnvDTE.vsBuildAction) Handles BuildEvents.OnBuildBegin
            If DTE.Solution.FullName.EndsWith(Path.DirectorySeparatorChar & "[Solution File Name]") Then
                If Scope = vsBuildScope.vsBuildScopeSolution And Action = vsBuildAction.vsBuildActionRebuildAll Then
                    AutoGenerateBuildNumber()
                End If
            End If
        End Sub
    End Module
    
    模块组装信息帮助.vb

    Public Module AssemblyInfoHelper
    
        ReadOnly AssemblyInfoPath As String = Path.Combine("Common", "GlobalAssemblyInfo.cs")
    
        Sub AutoGenerateBuildNumber()
    
            'Declear required variables
            Dim solutionPath As String = Path.GetDirectoryName(DTE.Solution.Properties.Item("Path").Value)
            Dim globalAssemblyPath As String = Path.Combine(solutionPath, AssemblyInfoPath)
            Dim globalAssemblyContent As String = ReadFileContent(globalAssemblyPath)
            Dim rVersionAttribute As Regex = New Regex("\[[\s]*(\/\*[\s\S]*?\*\/)?[\s]*assembly[\s]*(\/\*[\s\S]*?\*\/)?[\s]*:[\s]*(\/\*[\s\S]*?\*\/)?[\s]*AssemblyVersion[\s]*(\/\*[\s\S]*?\*\/)?[\s]*\([\s]*(\/\*[\s\S]*?\*\/)?[\s]*\""([0-9]+)\.([0-9]+)(.([0-9]+))?(.([0-9]+))?\""[\s]*(\/\*[\s\S]*?\*\/)?[\s]*\)[\s]*(\/\*[\s\S]*?\*\/)?[\s]*\]")
            Dim rVersionInfoAttribute As Regex = New Regex("\[[\s]*(\/\*[\s\S]*?\*\/)?[\s]*assembly[\s]*(\/\*[\s\S]*?\*\/)?[\s]*:[\s]*(\/\*[\s\S]*?\*\/)?[\s]*AssemblyInformationalVersion[\s]*(\/\*[\s\S]*?\*\/)?[\s]*\([\s]*(\/\*[\s\S]*?\*\/)?[\s]*\""([0-9]+)\.([0-9]+)(.([0-9]+))?[\s]*([^\s]*)[\s]*(\([\s]*Build[\s]*([0-9]+)[\s]*\))?\""[\s]*(\/\*[\s\S]*?\*\/)?[\s]*\)[\s]*(\/\*[\s\S]*?\*\/)?[\s]*\]")
    
            'Find Version Attribute for Updating Build Number
            Dim mVersionAttributes As MatchCollection = rVersionAttribute.Matches(globalAssemblyContent)
            Dim mVersionAttribute As Match = GetFirstUnCommentedMatch(mVersionAttributes, globalAssemblyContent)
            Dim gBuildNumber As Group = mVersionAttribute.Groups(9)
            Dim newBuildNumber As String
    
            'Replace Version Attribute for Updating Build Number
            If (gBuildNumber.Success) Then
                newBuildNumber = GenerateBuildNumber(gBuildNumber.Value)
                globalAssemblyContent = globalAssemblyContent.Substring(0, gBuildNumber.Index) + newBuildNumber + globalAssemblyContent.Substring(gBuildNumber.Index + gBuildNumber.Length)
            End If
    
            'Find Version Info Attribute for Updating Build Number
            Dim mVersionInfoAttributes As MatchCollection = rVersionInfoAttribute.Matches(globalAssemblyContent)
            Dim mVersionInfoAttribute As Match = GetFirstUnCommentedMatch(mVersionInfoAttributes, globalAssemblyContent)
            Dim gBuildNumber2 As Group = mVersionInfoAttribute.Groups(12)
    
            'Replace Version Info Attribute for Updating Build Number
            If (gBuildNumber2.Success) Then
                If String.IsNullOrEmpty(newBuildNumber) Then
                    newBuildNumber = GenerateBuildNumber(gBuildNumber2.Value)
                End If
    
                globalAssemblyContent = globalAssemblyContent.Substring(0, gBuildNumber2.Index) + newBuildNumber + globalAssemblyContent.Substring(gBuildNumber2.Index + gBuildNumber2.Length)
            End If
    
            WriteFileContent(globalAssemblyPath, globalAssemblyContent)
    
        End Sub
    
        Function GenerateBuildNumber(Optional ByVal oldBuildNumber As String = "0") As String
    
            oldBuildNumber = Int16.Parse(oldBuildNumber) + 1
    
            Return oldBuildNumber
    
        End Function
    
        Private Function GetFirstUnCommentedMatch(ByRef mc As MatchCollection, ByVal content As String) As Match
            Dim rSingleLineComment As Regex = New Regex("\/\/.*$")
            Dim rMultiLineComment As Regex = New Regex("\/\*[\s\S]*?\*\/")
    
            Dim mSingleLineComments As MatchCollection = rSingleLineComment.Matches(content)
            Dim mMultiLineComments As MatchCollection = rMultiLineComment.Matches(content)
    
            For Each m As Match In mc
                If m.Success Then
                    For Each singleLine As Match In mSingleLineComments
                        If singleLine.Success Then
                            If m.Index >= singleLine.Index And m.Index + m.Length <= singleLine.Index + singleLine.Length Then
                                GoTo NextAttribute
                            End If
                        End If
                    Next
    
                    For Each multiLine As Match In mMultiLineComments
                        If multiLine.Success Then
                            If m.Index >= multiLine.Index And m.Index + m.Length <= multiLine.Index + multiLine.Length Then
                                GoTo NextAttribute
                            End If
                        End If
                    Next
    
                    Return m
                End If
    NextAttribute:
            Next
    
            Return Nothing
    
        End Function
    
    End Module
    
    公共模块AssemblyInfoHelper
    只读AssemblyInfoPath格式为String=Path.Combine(“Common”、“GlobalAssemblyInfo.cs”)
    子自动生成buildNumber()
    '清除必需的变量
    Dim solutionPath作为字符串=Path.GetDirectoryName(DTE.Solution.Properties.Item(“Path”).Value)
    Dim globalAssemblyPath作为字符串=路径。组合(solutionPat