2015-05-04 21 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

相关问题