2013-08-28 33 views
5

我有一個字符串,格式如下。 (我加了標記,以獲得新行,以顯示正確)多行正則表達式匹配第一次出現但不能匹配第二個

-- START BELOW THIS LINE -- 
2013-08-28 00:00:00 - Tom Smith (Work notes) 
Blah blah 

b;lah blah 

2013-08-27 00:00:00 - Tom Smith (Work notes) 
ZXcZXCZXCZX 
ZXcZXCZX 
ZXCZXcZXc 
ZXCZXC 


-- END ABOVE THIS LINE -- 

我想獲得一個正則表達式,讓我來提取字符串的兩個獨立的部分信息。

下面的表達式第一部分匹配成功:

^(\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}) - (.*) \\(Work notes\\)\n([\\w\\W]*)(?=\n\n\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2} - .* \\(Work notes\\)\n) 

我試圖找出一個辦法,我可以修改它來獲取字符串的第二部分。我嘗試過類似下面的內容,但最終將匹配擴展到了字符串的末尾。它就像是優先考慮OR之後的表達式。

^(\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}) - (.*) \\(Work notes\\)\n([\\w\\W]*)(?:(?=\n\n\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2} - .* \\(Work notes\\)\n)|\n\\Z) 

任何幫助,將不勝感激

- 編輯 -

這裏是我創建嘗試並獲得這個正確的測試程序的副本。在這種情況下,我還添加了第三條消息,並且我的RegEx突破了。

using System; 
using System.Text.RegularExpressions; 

namespace RegExTest 
{ 
    class MainClass 
    { 
    public static void Main (string[] args) 
    { 
     string str = "2013-08-28 10:50:13 - Tom Smith (Work notes)\nWhat's up? \nHow you been?\n\n2013-08-19 10:21:03 - Tom Smith (Work notes)\nWork Notes\n\n2013-08-19 10:10:48 - Tom Smith (Work notes)\nGood day\n\n"; 
     var regex = new Regex ("^(\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}) - (.*) \\(Work notes\\)\n([\\w\\W]*)\n\n(?=\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2} - .* \\(Work notes\\)\n)",RegexOptions.Multiline); 

     foreach (Match match in regex.Matches(str)) 
     { 
     if (match.Success) 
     { 
      for (var i = 0; i < match.Groups.Count; i++) 
      { 
      Console.WriteLine('>'+match.Groups [i].Value); 
      } 
     } 
     } 

     Console.ReadKey(); 
    } 
    } 
} 

- 編輯 -

只是要清楚,我想提取數據的日期和時間標記(作爲一個項目),名稱,和「身體」來自每個「段落」。

+0

我們可以看到您的通話代碼嗎? – Botonomous

+0

你能發佈你用來構造正則表達式對象並執行匹配的確切代碼嗎?你很可能沒有使用正確的標誌。 –

+0

什麼可以出現在每個段落的正文中? –

回答

0

這是一個非常結實的一塊,你現在看到正則表達式。

雖然你可以做多條線的正則表達式,它只是複雜的東西。另外,因爲你有重複的模式,所以在換行符上分割你的字符串會更清晰,然後匹配每一行。最後,如果您打算從文件中獲取該文件,則很容易匹配文件的每一行,而不是讀取整個文件然後進行匹配。

這裏是我會做:

var regex = new Regex ("(\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}) - (.*?) \\(Work notes\\)"); 

var lines = str.split(new char[] {'\n'}); 

foreach (var line in lines) 
{ 
    var match = regex.Match(line); 

    if (match.Success) 
    { 
    for (var i = 0; i < match.Groups.Count; i++) 
    { 
     Console.WriteLine('>' + match.Groups[i].Value); 
    } 

    // will preface the body after each header 
    Console.WriteLine(">"); 
    } 
    else 
    { 
    Console.WriteLine(line); 
    } 
} 

至於你的正則表達式去,我維護你有原始的羣體,所以我們得到一個組中的日期/時間戳記,並在其他名稱。身體沒有被匹配到一個組,但是構建一個身體字符串將是微不足道的。

  1. (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})匹配組1

  2. -匹配,但不進行分組。

  3. (.*?)匹配2.集團

  4. \(Work notes\)匹配,但不進行分組。

+0

我原本是一行一行的做,但我的老闆認爲多行的正則表達式不會讓人困惑。我現在非常懷疑。 – Jason

0

正則表達式是不是真的這樣做的正確的解決方案,但如果你必須...

你的問題是與啓動正則表達式匹配貪婪的組合^。如果它以^開始,它需要它來啓動字符串,並且它不會在其他地方匹配。

.*的貪婪可以通過改爲.*?來解決。

試試這個:

(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) - (.*?) \(Work notes\)\n([\w\W]*?)((?=\n\n\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} - .*? \(Work notes\)\n)|((\s{0,})$)) 
+0

即時獲得它,但它將「身體」分成不同的組。如果您有RegEx以外的方法,請隨時提出建議。 – Jason

+0

當我在最後一次編輯中添加第三項時,它也失敗。 – Jason

0

我能得到一個表達式的工作,但它看起來有點嚇人我想:

@"([0-9\s:-]+)(?>\s-\s)(?>[^\n\r]+[\r\n]*)((?=[^0-9]+(\d{4}-\d{2}-\d{2}|$))[\s\S])+" 

@前的公式,使這個逐字字符串,所以你不會有翻番逃避一切。

注意:這不是正確的方式去做這件事,但我想試試。

+0

對不起,這沒有做到。如果我沒有記錯的話,它沒有得到全身。 – Jason

+0

@Jason OK謝謝你的回覆。 –

相關問題