C#正则表达式问题:含可选数据点的分组提取失败排查
First, let's break down why your current regex fails on the second line, then build a solution that meets all your requirements:
Key Issues with Your Existing Regex
Forced "1" in the Description Field
Yourdescrgroup uses\w+\s+.*?(1), which requires the description to contain the digit "1". The second line's description (OTHER VOLUME FEES) has no "1", so the regex stops matching immediately here—this is the main failure point.Ignoring Square Bracket Structure
Your regex doesn't account for the fact that all values are wrapped in[], leading to messy pattern matching for dates, volumes, and rates.No Support for Optional Fields
You mentionedVOLUMEorRATEmight be missing, but your current regex forces matches for both, which will break lines with missing fields.Limited Volume Matching
The volume pattern only matches numbers/decimals, but you need to support values like "1B" (letters included).
Corrected C# Regex
This regex handles all your edge cases, including optional fields, volume codes, and open-ended descriptions:
^\w+\s+\w+\s+\w+\s+\w+\s+\w+\s+\w+\s+\[(?<date>[^\]]+)\]\s+\[(?<type>[A-Za-z]{2})\]\s+\[(?<descr>[^\]]+)\](?:\s+\[(?<volume>[^\]]+)\])?(?:\s+\[(?<rate>[0-9.]+)\])?\s+\[(?<total>[-+]?[0-9.,]+)\]$
Breakdown of the Pattern
^\w+\s+\w+\s+\w+\s+\w+\s+\w+\s+\w+\s+: Matches the leading field names (DATE TYPE DESCR VOLUME RATE TOTAL) and their spacing.\[(?<date>[^\]]+)\]: Captures the date value inside square brackets (matches any characters except]).\s+\[(?<type>[A-Za-z]{2})\]: Captures the 2-letter type code inside brackets.\s+\[(?<descr>[^\]]+)\]: Captures the full description (any content inside brackets, no forced "1" requirement).(?:\s+\[(?<volume>[^\]]+)\])?: Optional group for volume—matches any content inside brackets (including codes like "1B"). The?:makes it non-capturing, and?marks it as optional.(?:\s+\[(?<rate>[0-9.]+)\])?: Optional group for rate—matches numbers/decimals inside brackets, marked as optional.\s+\[(?<total>[-+]?[0-9.,]+)\]$: Mandatory group for total—matches positive/negative numbers with commas or decimals, ensuring it's the final value in the line.
Testing the Regex
Example Line 1
Input:DATE TYPE DESCR VOLUME RATE TOTAL [11/30/15] [CF] [DISC 1] [28270.18] [0.00150] [-42.41]
date:11/30/15type:CFdescr:DISC 1volume:28270.18rate:0.00150total:-42.41
Example Line 2
Input:DATE TYPE DESCR VOLUME RATE TOTAL [11/30/15] [CF] [OTHER VOLUME FEES] [28186.68] [0.00008] [-2.25]
date:11/30/15type:CFdescr:OTHER VOLUME FEESvolume:28186.68rate:0.00008total:-2.25
Case with Missing Rate
Input:DATE TYPE DESCR VOLUME RATE TOTAL [11/30/15] [CF] [NO RATE] [100B] [] [-15.00]
volume:100Brate: (empty, as expected)total:-15.00
C# Usage Notes
- Access groups using
match.Groups["date"].Value,match.Groups["descr"].Value, etc. - Check if optional groups exist with
match.Groups["rate"].Successbefore accessing their values to avoid null/empty errors.
内容的提问来源于stack exchange,提问作者George Rios

