2015-11-10 35 views
2

我想從日誌文件中提取一些文本,並遇到問題。 示例文本我的工作是:日誌文件PowerShell正則表達式捕獲太多

ahksjhadjsadhsah 
sakdsjakdjks 
ksajdksaj 
REF=35464 
sadsad 
213213 
213 
2 
13 

我需要提取值「35464」(REF號碼)。我對正則表達式的瞭解有限,但認爲'REF =([0-9] +)'會這樣做。

現在我不知道我如何最好應該做的閱讀這個文件,所以我已經嘗試了幾種方法:

select-string -path e:\powershell\log.txt -pattern 'REF=([0-9]+)' | % { $_.Matches } | % { $_.Value } 

這給了我「REF = 35464」 - 這我不(理解爲什麼包含REF),因爲我認爲'捕獲'只是()的部分?

我也試過:

$data=Get-Content e:\powershell\log.txt 
$data -match 'REF=([0-9]+)' 
$Matches 

但是$匹配是空的。

我還嘗試了類似的方法除上述之外,但一行行,例如:

foreach ($line in $data) 
{ 
    $line -match 'REF=([0-9]+)' 
} 

我要麼得到沒有匹配時,或完全匹配(包括REF =部分)。我也嘗試過組(即'(REF =)([0-9] +)'),我無法得到我所需要的。

我該如何閱讀文件?我的正則表達式有什麼問題?

我只是需要這個提取的值作爲一個可用的變量。

+0

嘗試' '(<= REF =?)[0-9] +''如果你只需要號碼。 –

回答

1

它可能是你正在試圖訪問捕獲組

我把這個快速靜態類一同來說明如何得到你正在尋找匹配的方式。

注意:我在正則表達式和輸入字符串上使用@符號使它們成爲文字。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Text.RegularExpressions; 
using System.Threading.Tasks; 

namespace SkunkWorks.RegexPractice 
{ 
    public static class RegexPractice2 
    { 
     public static string input = @"ahksjhadjsadhsah 
     sakdsjakdjks 
     ksajdksaj 
     REF=35464 
     sadsad 
     213213 
     213 
     2 
     13"; 

     static string pat = @"REF=([0-9]+)"; 

     public static void Do() 
     { 
      Regex r = new Regex(pat, RegexOptions.IgnoreCase); 

      Match m = r.Match(input); 

      int matchCount = 0; 

      while (m.Success) 
      { 
       Console.WriteLine("Match" + (++matchCount)); 
       for (int i = 1; i <= 2; i++) 
       { 
        Group g = m.Groups[i]; 
        Console.WriteLine("Group" + i + "='" + g + "'"); 
        CaptureCollection cc = g.Captures; 
        for (int j = 0; j < cc.Count; j++) 
        { 
         Capture c = cc[j]; 
         System.Console.WriteLine("Capture" + j + "='" + c + "', Position=" + c.Index); 
        } 
       } 
       m = m.NextMatch(); 
      } 
     } 
    } 
} 
0

,當我需要從一個字符串數組抽取子我最常做的是使用從在Where語句中使用-match操作所產生的自動變量$Matches。就像這樣:

$Data | Where{$_ -match "REF=([0-9]+)"} | ForEach{$Matches[1]} 

現在,$Matches變量會有一個數組。第一個條目將是它匹配的整條線,第二個對象將只是捕獲的文本,這就是我指定[1]的原因。現在,關於您的RegEx,您在...上匹配......技術上它是可以接受的,但它不是特定的,所以它真的可以返回第一個數字,因爲[0-9]+意味着一個或多個字符落入[0-9]範圍內。如果您想要確保獲得所有數字,您可以通過在比賽中使用行尾字符$來讓所有內容都到達行尾,例如:REF=([0-9]+)$。我們無法確定數字後面是否有空格,因此您可能還想使用\s表示法來查找任何空格字符(空格,製表符,等等),並使用後面的星號(意思是零)或者更多。然後它變成REF=([0-9]+)\s*$,這正是你正在尋找的東西。最後,我會使用\d而不是[0-9],因爲它做同樣的事情,它更短,更簡單,並且專門用於這項工作。因此,我們有:

$Data | Where{$_ -match "REF=(\d+)\s*$"} | ForEach{$Matches[1]} 

,這是細分步步這裏解釋:https://regex101.com/r/dG7jC7/1