【问题标题】:Regular Expression to get substrings in PowerShell在 PowerShell 中获取子字符串的正则表达式
【发布时间】:2015-11-12 11:44:57
【问题描述】:

我需要有关正则表达式的帮助。我在一个文件中有 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
  }


}    

【问题讨论】:

标签: regex powershell


【解决方案1】:

假设你有那些在 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]} } }

【讨论】:

  • 谢谢阿迪尔.. 这是完美的!!
  • 你可以编辑它,使它也能像这样返回完整路径:-
  • 你可以编辑它,以便它可以像这样返回这个完整路径 [COMPILED]C:\project\Rom\Main\Plan\file1.file2.file3\Cmd\Camera.culture.less- Late-PP.min.js
  • 我仍然想要文件路径中的扩展名,你也可以单独提供帮助吗?
  • 嘿@a6k006,这很容易做到。您所要做的就是扩大第一个括号的限制。
猜你喜欢
  • 2013-06-25
  • 2017-06-07
  • 2011-06-26
  • 2019-03-30
  • 1970-01-01
  • 2014-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多