令我惊讶的是,我无法找到一个答案或一个例子,说明用正则表达式解析文本应该是一个相当常见的问题。我正在使用原生C#正则表达式;不是第三方组装。
这是嵌套列表的问题;例如,我说我有一个具有已定义格式的文本文件,但我想在一个类中构建它(下面的假设示例):
Input Text
Name: Joe Smith
Occupation: Software Developer
Patent(s) Awarded: 3 award(s)
Light Bulb
Rollercoasters
NTFS
Desired Output是一个具有类似的匹配项:
MatchCollection.Groups["Name"].Value
MatchCollection.Groups["Occupation"].Value
MatchCollection.Groups["AwardCount"].Value
... and then some form of list for the individual patents...
e.g. MatchCollection.Groups["Award"][0].Value
e.g. MatchCollection.Groups["Award"][1].Value
e.g. MatchCollection.Groups["Award"][2].Value
... and so on ...
现在正在做的是获取所有非列表信息并将专利列表视为单个字符串的第一步; e.g:
Name:\s+(?<Name>.+)\nOccupation:\s+(?<Occupation>.+)\nPatent\(s\) Awarded:\s+(?<AwardCount>\d+).*\n(?<AwardInfo>(?:.*\r\n)*)
...然后在专利清单上进行二次通过,以创建可列举的专利字符串列表。如果有下面的结构告诉正则表达式,你希望这个子表达式术语在它发生的时候被拾取,那将是很好的:
(?<AwardInfo>(?:.*\r\n)*)*
^
Which would return a second list to the Match object.
我是否忽略了一些简单的输出,使我能够遍历各项专利?如果没有,有人创造性地只使用一个正则表达式来解决这个问题吗?
答案 0 :(得分:5)
如果您设置正则表达式,以便<AwardInfo>
单独匹配每一行 - 通过移动组外的*
(并修剪空格,并使换行符可选):
(?:\s*(?<AwardInfo>.*(?:\r\n)?))*
然后您可以使用该组中的Captures
属性来获取该组匹配的每个不同值。例如,
MatchCollection[0].Groups["AwardInfo"].Captures[0] is "Light Bulb"
MatchCollection[0].Groups["AwardInfo"].Captures[1] is "Rollercoasters"
MatchCollection[0].Groups["AwardInfo"].Captures[2] is "NTFS"