如何基于自定义格式字符串提取字符串中的变量值?
解决方案
一、先修复当前正则的问题
你当前正则的第三个分组错误包含左括号,原因是多写了一层括号,且未将(作为非捕获的分隔符处理。修正后的正则如下:
var expression = new Regex(@"(?<Number>[^.]+)\. (?<First>[^-]+) - (?<Second>[^(]+) \((?<Third>[^)]+)\)");
执行后第三个值不会再带左括号,输出结果为:
1
Line One
Part Two
Optional Third Part
二、自动将友好格式字符串转为正则(核心需求)
要实现用户友好的格式字符串(如%number%. %first% - %second% (%third%))自动转换为正则,可按以下步骤实现:
1. 转换逻辑说明
- 识别格式字符串中的占位符:以
%包裹的字符串(如%number%)作为正则捕获组的名称 - 转义固定文本中的正则特殊字符:
.、(、)等符号属于正则特殊字符,需要转义后再作为匹配规则 - 将占位符替换为对应捕获组:用非贪婪匹配规则避免过度捕获内容
2. 代码示例
using System.Text.RegularExpressions; var input = "1. Line One - Part Two (Optional Third Part)"; var formatString = "%number%. %first% - %second% (%third%)"; // 提取所有占位符名称 var placeholders = Regex.Matches(formatString, @"%(\w+)%") .Cast<Match>() .Select(m => m.Groups[1].Value) .ToList(); // 转义格式字符串中的正则特殊字符,再替换占位符为捕获组 var regexPattern = Regex.Escape(formatString); foreach (var placeholder in placeholders) { var escapedPlaceholder = Regex.Escape($"%{placeholder}%"); // 用[\s\S]*?实现非贪婪匹配,适配大多数场景 regexPattern = regexPattern.Replace(escapedPlaceholder, $"(?<{placeholder}>[\\s\\S]*?)"); } // 添加首尾锚点,确保输入完全匹配格式 regexPattern = $"^{regexPattern}$"; var expression = new Regex(regexPattern); var match = expression.Match(input); if (match.Success) { foreach (var placeholder in placeholders) { Console.WriteLine(match.Groups[placeholder].Value.Trim()); } }
三、无需正则的替代方案(适合简单格式)
如果格式的分隔符唯一且不会出现在变量值中,可以用分割法实现:
var input = "1. Line One - Part Two (Optional Third Part)"; var formatString = "%number%. %first% - %second% (%third%)"; // 提取格式中的固定分隔符 var separators = Regex.Split(formatString, @"%\w+%") .Where(s => !string.IsNullOrWhiteSpace(s)) .ToList(); // 按分隔符分割输入内容 var parts = input.Split(separators, StringSplitOptions.RemoveEmptyEntries); // 对应提取变量值 var number = parts[0].Trim(); var first = parts[1].Trim(); var second = parts[2].Trim(); var third = parts[3].Trim('(', ')'); Console.WriteLine(number); Console.WriteLine(first); Console.WriteLine(second); Console.WriteLine(third);
局限
- 分隔符不能出现在变量值中,否则会导致分割错误
- 无法处理嵌套或复杂格式
内容的提问来源于stack exchange,提问作者Ryan Thomas
相关产品推荐
相关产品推荐

