鉴于我正在解析的2条不同的行,我需要将数据点提取到正则表达式匹配组中。
示例第1行:
标题值如下:
DATE{space}TYPE{space}DESCR{space}VOLUME{space}RATE{space}TOTAL
[11/30/15] [CF] [DISC 1] [28270.18] [0.00150] [-42.41]
第2行示例:
DATE{space}TYPE{space}DESCR{space}VOLUME{space}RATE{space}TOTAL
[11/30/15] [CF] [OTHER VOLUME FEES] [28186.68] [0.00008] [-2.25]
我正在使用以下正则表达式来获取匹配项:
(?<date>^\d{1,2}[-/.]\d{1,2}[-/.]\d{1,2}[\d+])\s+(?<type>[A-Za-z]{2})\s+(?<descr>\w+\s+.*?(1))\s+.*?(?<volume>(\d+(?:\.\d+?))\s+.*?(?<rate>([0]?(\d+(?:\.\d+)?)))\s+(?<total>[-+]?\d+[.,]\d+)?.*$")
我可以匹配第一种情况,但绝不是第二种情况。总会有总数,但它们可能并不总是数量或费率。另外,音量可以是整数,十进制或代码(例如“1B”)。
我在这里缺少什么?
描述字段是一个空白字段,其中可能包含“1”。我可以在其中加上几个单词,或者只是1.
答案 0 :(得分:2)
您的日志行包含6个字段,但第4个和第5个字段可能会丢失。匹配可选字段的常用方法是使用可选的非捕获组,(?:...)?
。这些组不会为它们匹配的文本创建单独的内存缓冲区,这就是为什么它们对于保持匹配更清晰和更有效的有用。
注意在.NET中,有一种方法可以使用RegexOptions.ExplicitCapture
选项使所有非命名捕获组无法捕获。
你的固定正则表达式看起来像
^(?<date>\d{1,2}[-/.]\d{1,2}[-/.]\d{1,2})\s+(?:(?<type>[A-Z]{2})\s+)?(?:(?<descr>\w.*?)\s+)?(?:(?<volume>\d*\.?\d+)\s+)?(?:(?<rate>\d*\.?\d+)\s+)?(?<total>[-+]?\d*[.,]?\d+)\s*$
请参阅.NET regex demo。
<强>详情
^
- 开始一行(使用RegexOptions.Multiline
时)(?<date>\d{1,2}[-/.]\d{1,2}[-/.]\d{1,2})
- 小组&#34;日期&#34;:1-2位数字,然后重复-
/ /
/ .
,然后重复1-2次数字(因此,此模式可以写为(?<date>\d{1,2}(?:[-/.]\d{1,2}){2})
)。\s+
- 一个或多个空格(?:(?<type>[A-Z]{2})\s+)?
- 一个匹配2个大写ASCII字母的可选组,捕获到Group&#34; type&#34;,然后是1 + whitespaces (?:(?<descr>\w.*?)\s+)?
- 一个匹配单词char(字母,数字或_
和其他一些特殊字符(如变音符号)的可选组,后跟除了换行符char LF之外的任何0 +字符,只有少数尽可能将所有这些捕获到Group&#34; descr&#34;,然后是1 + whitespaces (?:(?<volume>\d*\.?\d+)\s+)?
- 一个可选的组,匹配0+个数字,一个可选的.
,然后是1+个数字(即浮点数或整数),被捕获到Group&#34; volume&#34 ;,然后1+空白字符(?:(?<rate>\d*\.?\d+)\s+)?
- 一个可选的组,用于匹配捕获到Group&#34; rate&#34;,然后是1+空格字符的浮点值或整数值(?<total>[-+]?\d*[.,]?\d+)
- 小组&#34;总计&#34;:可选-
或+
后跟0+位数,可选.
或{{1}然后1+位数(所以,正或负浮点数或整数匹配),
- 任何0+尾随空格\s*
- 行尾。答案 1 :(得分:0)
(?<date>^\d{1,2}[-/.]\d{1,2}[-/.]\d{1,2}[\d+])\s+(?<type>[A-Z]{2})\s+(?<descr>\w+.*?\s+)(?<volume>\d+[.]?\d+)\s+(?<rate>\d+[.]?\d+)\s+(?<total>[-+]?\d+[.,]\d+?.*$)
是。这是一个相当复杂的正则表达式。但是如果你的分组中有不同的空格,你可以使用。*?\ s +来结束最后一个空格。对于我拥有的所有用例,这似乎都很好用。
感谢您的评论!