regex - 在PowerShell中使用正则表达式获取子字符串

标签 regex powershell

我需要有关正则表达式的帮助。我的文件中有 1000 行,格式如下:

 + + [COMPILED]\SRC\FileCheck.cs                               - TotalLine:   99 RealLine:   27 Braces:   18 Comment:   49 Empty:    5
 + + [COMPILED]\SRC\FindstringinFile.cpp                                  - TotalLine:  103 RealLine:   26 Braces:   22 Comment:   50 Empty:    5
 + + [COMPILED]\SRC\findingstring.js                                - TotalLine:   91 RealLine:   22 Braces:   14 Comment:   48 Empty:    7
 + + [COMPILED]\SRC\restinpeace.h                      - TotalLine:   95 RealLine:   24 Braces:   16 Comment:   48 Empty:    7
 + + [COMPILED]\SRC\Getsomething.h++                               - TotalLine:  168 RealLine:   62 Braces:   34 Comment:   51 Empty:   21
 + + [COMPILED]\SRC\MemDataStream.hh                             - TotalLine:  336 RealLine:  131 Braces:   82 Comment:   72 Empty:   51
 + + [CONTEXT]\SRC\MemDataStream.sql                             - TotalLine:  36 RealLine:  138 Braces:   80 Comment:   76 Empty:   59

我需要一个可以给我的正则表达式:

  • 文件路径,即\SRC\FileMap.cpp
  • 扩展名,即.cpp
  • RealLine 值,即 17

我使用 PowerShell 来实现此目的,并使用 Get-Content(读取文件)和 Select-String cmdlet 成功获取结果。 问题是它需要很长时间才能获取各种子字符串,然后将它们写入 xml 文件中。(我还没有放入生成和 xml 的代码)。 我以前从未使用过正则表达式,但我知道使用正则表达式将是获取字符串的有效方法..

如果有帮助,我们将不胜感激。

Select-String cmdlet 接受正则表达式来搜索字符串。

当前代码如下:

    function Get-SubString
    {
        Param ([string]$StringtoSearch, [string]$StartOfTheString, [string]$EndOfTheString)
        If($StringtoSearch.IndexOf($StartOfTheString) -eq -1 )
        {
            return
        }

        [int]$StartOfIndex = $StringtoSearch.IndexOf($StartOfTheString) + $StartOfTheString.Length
        [int]$EndOfIndex = $StringtoSearch.IndexOf($EndOfTheString , $StartOfIndex)
        if( $StringtoSearch.IndexOf($StartOfTheString)-ne -1 -and $StringtoSearch.IndexOf($EndOfTheString) -eq -1 )
        {
         [string]$ExtractedString=$StringtoSearch.Substring($StartOfTheString.Length)
        }
        else
        {
        [string]$ExtractedString = $StringtoSearch.Substring($StartOfIndex, $EndOfIndex - $StartOfIndex)
        }
        Return $ExtractedString

    }

   function Get-FileExtension
   {
      Param ( [string]$Path)
      [System.IO.Path]::GetExtension($Path)
   }


 #For each file extension we will be searching all lines starting with + +
  $SearchIndividualLines = "+ + ["
   $TotalLines = select-string -Pattern $SearchIndividualLines -Path   
   $StandardOutputFilePath -allmatches -SimpleMatch

  for($i = $TotalLines.GetLowerBound(0); $i -le $TotalLines.GetUpperBound(0); $i++)

{
$FileDetailsString = $TotalLines[$i]
#Get File Path
$StartStringForFilePath = "]"

  $EndStringforFilePath =  "- TotalLine"

   $FilePathValue = Get-SubString -StringtoSearch $FileDetailsString -StartOfTheString $StartStringForFilePath -EndOfTheString $EndStringforFilePath

  #Write-Host FilePathValue is $FilePathValue

  #GetFileExtension
  $FileExtensionValue = Get-FileExtension -Path $FilePathValue
  #Write-Host FileExtensionValue is $FileExtensionValue

  #GetRealLine
  $StartStringForRealLine = "RealLine:"
  $EndStringforRealLine =  "Braces"
     $RealLineValue = Get-SubString -StringtoSearch $FileDetailsString -
     StartOfTheString $StartStringForRealLine -EndOfTheString $EndStringforRealLine
  if([string]::IsNullOrEmpty($RealLineValue))
  {
  continue
  }


}    

最佳答案

假设您在 C:\temp\sample.txt 中有这些

类似这样的吗?

PS> (get-content C:\temp\sample.txt) | % { if ($_ -match '.*COMPILED\](\\.*)(\.\w+)\s*.*RealLine:\s*(\d+).*') { [PSCustomObject]@{FilePath=$matches[1]; Extention=$Matches[2]; RealLine=$matches[3]} } }

FilePath              Extention RealLine
--------              --------- --------
\SRC\FileCheck        .cs       27      
\SRC\FindstringinFile .cpp      26      
\SRC\findingstring    .js       22      
\SRC\restinpeace      .h        24      
\SRC\Getsomething     .h        62      
\SRC\MemDataStream    .hh       131

更新: 括号内的内容被捕获,因此如果您想捕获 [COMPILED],您只需将该部分添加到正则表达式中即可:

而不是

$_ -match '.*COMPILED\](\\.*) 

使用

$_ -match '.*(\[COMPILED\]\\.*)

您的问题评论中的链接包含有关正则表达式的良好入门知识。

更新2 现在您想要捕获路径集,我猜您的示例如下所示:

+ + [COMPILED]C:\project\Rom\Main\Plan\file1.file2.file3\Cmd\Camera.culture.less-Lat‌​e-PP.min.js    - TotalLine:  336 RealLine:  131 Braces:   82 Comment:   72 Empty:   51

上面的技术是可行的,你只需要对第一个括号做一个非常小的调整,如下所示:

$_ -match (\[COMPILED\].*)

这将告诉正则表达式您想要捕获 [COMPILED] 及其之后的所有内容,直到

(\.\w+)

即扩展名,由一个点和几个字母组成(如果您有像 .3gp 这样的扩展名,则可能不起作用)

因此,您原来的衬里将是:

(get-content C:\temp\sample.txt) | % { if ($_ -match '.(\[COMPILED\].*)(\.\w+)\s*.*RealLine:\s*(\d+).*') { [PSCustomObject]@{FilePath=$matches[1]; Extention=$Matches[2]; RealLine=$matches[3]} } }

关于regex - 在PowerShell中使用正则表达式获取子字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33620597/

相关文章:

java - Java 中的正则表达式(Spring 配置)开头有 2 个特定字符

Powershell ISE 缺少颜色输出

node.js - 如何从 package.json "scripts"执行 powershell ps1 脚本?

c# - 如何枚举真实的 Windows 文件资源管理器窗口

java正则表达式从文本中检索链接

javascript - 正则表达式匹配多个可能的选项

.net - RegEx 删除除 CR 或 LF 之外的所有控制/不可见字符

java - 从 div 标签中提取所有数字和罗马数字

powershell - 在powershell中,如何将下标的退出代码返回给调用脚本

powershell - 如何从PowerShell中的文件读取行