所以,我将这些来自SMSes的数据导出到我希望能够提取的文本,并创建一个比纯文本更好的报告,所以我有一个完整的这些行的文件:
1. 01 mag 2015 10:55:08 AM stringOne PersonName +999999999999 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)*)
我只得到一行。
那么,我怎样才能将最后一段“信息”作为多行文字?
答案 0 :(得分: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+\.|$)
将捕获多行文字,直到它找到一个有一个数字和.
的换行符。前瞻检查它但不消耗它
答案 1 :(得分: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.Singleline
和RegexOptions.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();
输出: