C# 为什么我最后一个命名的小组会捕获其他所有东西?
因此,我将这些来自SMSE的数据导出为文本,我希望能够提取并创建一个比纯文本更好的报告,因此我有一个包含以下行的文件:C# 为什么我最后一个命名的小组会捕获其他所有东西?,c#,.net,regex,C#,.net,Regex,因此,我将这些来自SMSE的数据导出为文本,我希望能够提取并创建一个比纯文本更好的报告,因此我有一个包含以下行的文件: 1. 01 mag 2015 10:55:08 AM stringOne PersonName +999999999999 MultilineText 让我把它分解一下: “1”就像一个行号 “2015年6月1日上午10:55:08”是日期 “stringOne”是可以是“stringOne”或“stringTwo”
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+)"
@“(?\d{1,3}\)(?\d{2}\w{3}\d{4}\d{2}\:\d{2}(AM | PM))\s*(stringOne | stringTwo)s*(?\w+)\s*(?\+\d+)
我尝试将以下部分添加到该正则表达式中:
(?<text>.*)
(?*)
然而,我没有正确地得到多行文本,我确实得到了一些数据,但是当它变成多行时,它被剪切掉了
然后,我试着用这个来代替:
(?<text>(.|\n)*)
(?(.|\n)*)
结果我只得到一行
那么,如何才能将最后一条信息作为多行文本获取呢?您缺少了使
匹配换行符的单行运算符,以及使我们能够控制行开始的多行选项(?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+\.)
看
您可能想知道\z
的作用是什么:它匹配字符串的结尾,而不考虑修改^
和$
锚点含义的多行标志
请检查C#代码:
var rx=new Regex(@“(?\d{1,3}\.\s+)(\d{2}\s+\w{3}\s+\d{4}\s+\d{2}\:\d{2}\:\d{2}\s*(AM | PM))\s*(stringOne | stringTwo+)*(?\w\s*(?\w\s*(?\+\d+)(?\d+)(*)(*,z=,?)\s*”;regions*(多行);
var strr=“1.01 mag 2015 10:55:08 AM stringOne PersonName+9999999999多行\r\n 2.01 mag 2015 10:55:08 AM stringOne PersonName+222 9999多行\r\n”;
var mth=rx.Matches(strr.Cast().ToList();
输出:
(?<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+\.|$)
(?\d{1,3}\)(?\d{2}\w{3}\d{4}\d{2}\:\d{2}(AM | PM))\s*(stringOne | stringTwo)\s*(?\w+)\s*(?[\s\s]*)(?=\n[]*\d+$)
你可以试试这个
(?[\s\s]*?)(?=\n[]*\d+\.\124;$)
将对多行文本进行catpure处理,直到它找到一个包含数字的换行符并且
。前瞻会检查它,但不会消耗它。注意,我从正则表达式中看到,
,stringOne>StringTwo>之间的空格(\s
),
和
是可选的(*
量词=0或更多)。可能是一个好主意,使它成为必需的?(+
quantifier=1或更多)@ohaal是的,lol,这可能是个好主意,因为它们确实是必需的=)非常感谢你的回答,但这并不能解决我的问题。我用这个正则表达式从MatchCollection中只得到一个匹配项。我需要正则表达式分析整个文件,而不是一个line@Robson:为什么不迭代每一行并应用正则表达式?我想这比在整个文件上使用正则表达式更便宜?@ohaal这是个好主意,尽管我不关心性能,但在这种情况下,我需要使用StringReader.ReadToEnd()立即分析整个文件,如果您有带项目符号的文本(每个条目以一个数字开头)++
++空格
,我的正则表达式应该正确处理它们。明白了!问题是我不太清楚数据是如何产生的。因此,只有当行以degits开头时,您的解决方案才起作用,如果有任何空格,正则表达式就会失败。@vks在您前面用“(?=\n[]*\d+\.\124;$”来表示它。”。但真的很感谢你帮了我很多忙!非常感谢!这似乎有效,你能解释一下“(?[\s]*?)(?=\n[]*\d+\.\124;$)”部分吗?我担心,因为我正在使用Match.Groups[“text”]。ToString()显示数据,一些文本将丢失“text”部分将只包含“[\s\s]*?”对吗?“先行检查它,但不使用它”指定此操作的命令是什么?@Robson(?=something)
。(?=
之后的任何内容都是向前看的,不会被使用
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();
(?<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+\.|$)