2017-10-11 63 views
1

我需要從類似於下面的sql日誌中解析和提取值。多行java的正則表達式

SQL^^0001^^ABCDEF^^26^^XYZ 
SQL^^0002^^ABCDEF^^26^^XYZ 
abc 
<>()_asc wHERE 
SQL^^0003^^ABCDEF^^12^^XYZ 
SQL^^0004^^ABCDEF^^28^^XYZ 

但是日誌總是不是單行。我有一個可以捕獲的正則表達式如果它是單行的。除了最後一個元素外,這些字段的長度也是固定的。最後一個元素的長度可能不同。

(\w{3})\W{2}(\d{4})\W{2}(\w{6})\W{2}(\d{2})\W{2}(.*) 

^^ is the delimiter but can be any other value also. 

沒有固定的行尾字符,但我需要捕獲,直到下一行SQL在這種情況下。 如何解析日誌並提取它們,如果它的多行日誌。我在Java中嘗試。 Java或Scala是首選。

+0

正則表達式的其餘部分不是輸入解析跨多行的好工具。如果所有感興趣的數據記錄都以相同的模式開始,那麼您可以做的一件事是將日誌讀入單行文本(不換行'\ n'字符),然後在開始時將'split()記錄模式。之後,您將解析各個元素。 – jwvh

+0

在每行的開頭是否有以「SQL ^^'開頭的新記錄?要正確處理這種情況,我們需要知道確切的記錄起始模式。嘗試[** this regex **](https://regex101.com/r/OrIqvz/1)。 –

+0

很高興爲你效勞。如果我的回答對你有幫助,也請考慮積極投票。 –

回答

0

您可以利用這樣的事實,即每個記錄始終以3個字符後跟^^開頭。因此,您匹配的最後一個字段應匹配任何不以該模式開頭的行。如果^^只是一個示例,則可以使用整個\w{3}\W{2}\d{4}\W{2}\w{6}\W{2}\d{2}\W{2}模式作爲分隔符而不是^^

使用

(?m)^(\w{3})\W{2}(\d{4})\W{2}(\w{6})\W{2}(\d{2})\W{2}(.*(?:\r?\n(?!\w{3}\^\^).*)*) 

regex demo。如果^^只是一個佔位符,如上所述,請將​​替換爲(?!\w{3}\W{2}\d{4}\W{2}\w{6}\W{2}\d{2}\W{2})。或者,也許更短的一個也會這樣做:(?!\w{3}\W{2}\d{4}\b)

詳細

  • (?m)^ - 一行的開始((?m)Pattern.MULTILINE嵌入標誌的選項,使得^匹配的線開始,而不是字符串開始位置)
  • (\w{3}) - 組1:3字詞
  • \W{2} - 2個非單詞字符
  • (\d{4}) - 第2組:四位數字
  • \W{2} - 2非字字符
  • (\w{6}) - 組3:6個字字符
  • \W{2} - 2非字字符
  • (\d{2}) - 組4:2位數字
  • \W{2} - 2個非字字符
  • (.*(?:\r?\n(?!\w{3}\^\^).*)*) - 第5組:
    • .* - 連續零個或多個 - 任何0+比換行符字符等,儘可能多的
    • (?:\r?\n(?!\w{3}\^\^).*)*字符:
      • \r?\n(?!\w{3}\W{2}) - CRLF或LF換行符後面沒有與3字,然後2個非字字符
      • .* - 行