使用Regular Expression在PowerShell中获取子字符串

时间:2015-11-10 00:00:39

标签: 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

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

  • FilePath即 \ 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
  }


}    

1 个答案:

答案 0 :(得分:2)

假设您有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

<强>更新 捕获内部paranthesis中的东西,因此如果要捕获[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]} } }
相关问题