2010-03-25 40 views
1

爲了匹配這些序列中的模式,我正在努力使用正則表達式將日誌文件拆分爲對數序列。 日誌格式是:java正則表達式:在標記之間捕獲多行序列

timestamp fieldA fieldB fieldn log message1 
timestamp fieldA fieldB fieldn log message2 
log message2bis 
timestamp fieldA fieldB fieldn log message3 

時間戳正則表達式是已知的。

我想提取時間戳之間的每個日誌序列(可能多行)。我想保留時間戳。

我想在同一時間保持行的確切數量。

我需要的是如何裝飾時間戳記模式,以便按日誌順序分割我的日誌文件。我不能將整個文件拆分爲字符串,因爲在CharBuffer中提供內容的文件

這裏是將要使用此日誌序列匹配樣品的方法:

private void matches(File f, CharBuffer cb) { 
    Matcher sequenceBreak = sequencePattern.matcher(cb); // sequence matcher 
    int lines = 1; 
    int sequences = 0; 

    while (sequenceBreak.find()) { 
     sequences++; 

     String sequence = sequenceBreak.group(); 
     if (filter.accept(sequence)) { 
      System.out.println(f + ":" + lines + ":" + sequence);     
     } 

     //count lines 
     Matcher lineBreak = LINE_PATTERN.matcher(sequence); 
     while (lineBreak.find()) { 
      lines++; 
     } 

     if (sequenceBreak.end() == cb.limit()) { 
      break; 
     } 
    }   
} 

回答

1

預定組\s這聽起來像你想正則表達式匹配整個日誌序列,從時間戳到最後一行的結尾,包括行分隔符。假設每個日誌序列但是最後一個日誌序列後面緊跟着另一個日誌序列,則應該能夠使用時間戳的前瞻來查找序列的結尾。

Pattern sequencePattern = pattern.compile(
    "^timestamp.*?(?=timestamp|\z)", 
    Pattern.DOTALL | Pattern.MULTILINE); 

如果這還不算快或不夠準確,這應該更好的工作:

Pattern sequencePattern = pattern.compile(
    "^timestamp.*+(?:(?:\r\n|[\r\n])(?!timestamp).*+)*+(?:\r\n|[\r\n])?", 
    Pattern.MULTILINE); 

當然,我假設你會真正的時間戳正則表達式替換timestamp。出於好奇,你有沒有考慮使用Scanner的findWithinHorizon方法呢?在我看來,它可以爲你節省很多工作。

+0

感謝Alan,我很高興您已經理解了我的問題,因爲即使對我自己的眼睛來說它看起來也很模糊...... 您是否建議我已經放棄正則表達式贊成掃描器,代碼更簡單,工作正常。 – Guillaume 2010-03-26 09:29:43

0

我不看看你的代碼中的任何正則表達式,但這裏有一個提示:

通過在正則表達式中對點.進行默認匹配匹配除了換行符之外的所有內容。如果你想以匹配新行,你需要Pattern.DOTALL作爲參數傳遞給Pattern.compile(str, flags)

的另一種方式,以配合新線是使用相匹配[\t\n\x0B\f\r]

+0

您可能還需要國旗Pattern.MULTILINE – 2010-03-25 12:03:59

1

如果我正確理解您的問題,您希望使用正則表達式拆分文件,但不能使用Java的內置Split()方法。在這種情況下,只需編寫自己的Split()方法。

迭代所有正則表達式匹配。對於第一場比賽,存儲比賽的時間戳和結束位置。對於後續的比賽,請將所存儲的前一場比賽結束位置與當前比賽開始位置之間的文本與前一場比賽相關聯。然後存儲當前比賽的時間戳和結束位置。循環結束後,取出存儲的最後一個匹配結束位置和文件結尾之間的文本,並將其與最後一個匹配關聯起來。

使用只匹配時間戳的正則表達式,並使用一些過程代碼來獲取時間戳之間的文本將比嘗試提出一個匹配時間戳的正則表達式和一切直到下一個時間戳。

+0

謝謝Jan,我正在考慮類似的東西來解決這個問題,但我希望能夠做到這一點的'神奇的正則表達式'。 – Guillaume 2010-03-26 09:25:37

+0

艾倫的答案與你所得到的「魔法」接近。但是,如果性能和可維護性對您很重要,我建議使用簡單的「timestamp」正則表達式,讓程序代碼按照我在答案中所述的方式完成工作。做「魔術」的正則表達式是有些人認爲他們是邪惡的原因。 – 2010-03-27 03:30:07