2015-05-04 48 views
2

所以,我有這些數據來自導出到文本,我希望能夠提取並創造出比純文本更好報告的短信,讓我有充分的這些行的文件:爲什麼我最後一個被命名的小組抓住了一切?

1. 01 mag 2015 10:55:08 AM stringOne PersonName      +999999999999 MultilineText 

設我把它分解下來:

  1. 「1.」就像是一個行數
  2. 「01 MAG 2015上午10時55分08秒」是日期
  3. 「stringOne」是可以是「stringOne」或「stringTwo」的字符串
  4. 「PERSONNAME」是一個表示人的姓名串
  5. 「999999999999」的電話號碼
  6. 「MultilineText」是可以包含任何

我使用Regex.Matches得到MatchCollection迭代上一個多串。

,我可以得到一切,如果我不包括在最後一組,我真的需要這些數據,所以這裏是我使用的成功檢索數據,而最後一組正則表達式的工作:

@"(?<lineNumber>\d{1,3}\. )(?<date>\d{2} \w{3} \d{4} \d{2}\:\d{2}\:\d{2} (AM|PM))\s*(stringOne|stringTwo)\s*(?<from>\w+)\s*(?<celnumber>\+?\d+)" 

我試着以下部分添加到正則表達式:

(?<text>.*) 

但是,我不能正確獲取多行文本,我得到了一些數據,但是當它多被切出。

然後,我曾嘗試使用它代替:

(?<text>(.|\n)*) 

我只得到一個行的結果。

那麼,如何才能將最後一塊「信息」作爲多行文本?

+1

在阿里納斯換行,我從你的正則表達式看出,空間('\ s') '','stringOne | StringTwo',''和''是可選的('*'量詞= 0或更多)。可能是一個好主意,使其成爲必需? ('+'量詞= 1或更多) – ohaal

+0

@ohaal是的,大聲笑,這可能是一個好主意,因爲他們的確需要=) – Robson

回答

2
(?<lineNumber>\d{1,3}\. )(?<date>\d{2} \w{3} \d{4} \d{2}\:\d{2}\:\d{2} (AM|PM))\s*(stringOne|stringTwo)\s*(?<from>\w+)\s*(?<celnumber>\+?\d+)\s*(?<text>[\s\S]*?)(?=\n[ ]*\d+\.|$) 

你可以試試這個。

(?<text>[\s\S]*?)(?=\n[ ]*\d+\.|$)將catpure多行文字,直到它發現其中有一個數字,.它.The先行檢查,但犯規消耗它

+0

非常感謝你!它似乎工作,你能解釋一下「(? [\ s \ S] *?)(?= \ n [] * \ d + \。| $)」部分?我擔心,因爲我使用Match.Groups [「text」]顯示數據。ToString()一些文本將丟失 – Robson

+0

「文本」部分將只包含「[\ s \ S] *?」對? – Robson

+0

@Robson對!!!!!!!!添加說明 – vks

1

你缺少的單線運營,這將使.匹配換行符符號,以及多選項(?m)這將使我們能夠控制的開始。我也建議更換與\s文字的空間,因爲它會與最終的未來調試幫助:

這裏是內嵌正則表達式(?s)(?m)選項:

(?sm)(?<lineNumber>\d{1,3}\.\s+)(?<date>\d{2}\s+\w{3}\s+\d{4}\s+\d{2}\:\d{2}\:\d{2}\s*(AM|PM))\s*(stringOne|stringTwo)\s*(?<from>\w+)\s*(?<celnumber>\+?\d+)(?<text>.*?)(?=\z|^\s*\d+\.) 

或程序內(RegexOptions.SinglelineRegexOptions.Multiline):

var rx = new Regex(@"(?<lineNumber>\d{1,3}\.\s+)(?<date>\d{2}\s+\w{3}\s+\d{4}\s+\d{2}\:\d{2}\:\d{2}\s*(AM|PM))\s*(stringOne|stringTwo)\s*(?<from>\w+)\s*(?<celnumber>\+?\d+)(?<text>.*?)(?=\z|^\s*\d+\.)", RegexOptions.Singleline|RegexOptions.Multiline); 

demo

您可能想知道\z的作用:它匹配字符串的末尾,而不考慮修改^$錨的含義的多行標誌。

請檢查C#代碼:

var rx = new Regex(@"(?<lineNumber>\d{1,3}\.\s+)(?<date>\d{2}\s+\w{3}\s+\d{4}\s+\d{2}\:\d{2}\:\d{2}\s*(AM|PM))\s*(stringOne|stringTwo)\s*(?<from>\w+)\s*(?<celnumber>\+?\d+)(?<text>.*?)(?=\z|^\s*\d+\.)", RegexOptions.Singleline | RegexOptions.Multiline); 
var strr = "1. 01 mag 2015 10:55:08 AM stringOne PersonName      +999999999999 Multiline\r\nText\r\n 2. 01 mag 2015 10:55:08 AM stringOne PersonName      +222229999 Multiline\r\nText"; 
var mth = rx.Matches(strr).Cast<Match>().ToList(); 

輸出:

enter image description here

+0

非常感謝您的回答,但它不能解決我的問題。我只使用這個正則表達式從MatchCollection中獲得一個Match。我需要正則表達式分析整個文件,而不僅僅是一行 – Robson

+0

@Robson:爲什麼不迭代每行並應用正則表達式?我會想象比在整個文件中使用正則表達式更便宜嗎? – ohaal

+0

@ohaal這是一個好主意,即使我認爲在這種情況下我並不關心性能,但我仍然使用StringReader.ReadToEnd()分析整個文件() – Robson

相關問題