为什么我最后一个被命名的小组会抓住其

时间:2015-05-04 10:24:12

标签: c# .net regex

所以,我将这些来自SMSes的数据导出到我希望能够提取的文本,并创建一个比纯文本更好的报告,所以我有一个完整的这些行的文件:

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

让我分解一下:

  1. “1”。就像一个行号
  2. “01 mag 2015 10:55:08 AM”是日期
  3. “stringOne”是一个字符串,可以是“stringOne”或“stringTwo”
  4. “PersonName”是表示人员姓名的字符串
  5. “+ 999999999999”是电话号码
  6. “MultilineText”是一个可以包含任何内容的多行字符串
  7. 我正在使用Regex.MatchesMatchCollection进行迭代。

    如果我不包含最后一个组,我可以让一切正常工作,我真的需要获取这些数据,所以这里是正在使用的正则表达式,它成功检索没有最后一组的数据:

    @"(?<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)*)
    

    我只得到一行。

    那么,我怎样才能将最后一段“信息”作为多行文字?

2 个答案:

答案 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.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