如何用CsvHelper拆分Excel HYPERLINK字段为URL与文本值?
如何用CsvHelper拆分Excel HYPERLINK格式的CSV字段
当然可以搞定这个需求!你遇到的这种Excel HYPERLINK公式格式的CSV字段,用CsvHelper完全可以拆分成独立的URL和公司名称两个值,我给你分享两种实用的实现方式:
核心思路
首先得解析这个HYPERLINK字符串的结构:你的示例字段是"=HYPERLINK("" https://app.redflagalert.net/search/company/00975699/ "",""CHILTERN HILLS MINERAL WATER LIMITED"")",其中CSV里的双引号是转义符(两个双引号代表一个实际的双引号),所以实际的公式结构是=HYPERLINK("URL", "显示文本")。我们可以用正则表达式精准提取出URL和显示文本这两个部分。
推荐用这个正则表达式:
=HYPERLINK\(""(.*?)""\s*,\s*""(.*?)""\)
它会匹配出两个分组:第一个分组是URL,第二个是公司名称,.*?是非贪婪匹配,避免抓取多余内容。
方式一:使用自定义ClassMap(推荐)
这种方式更符合CsvHelper的面向对象用法,适合结构化处理数据:
1. 定义数据模型
首先创建一个类来存储拆分后的数据:
public class CompanyLink { public string Url { get; set; } public string CompanyName { get; set; } }
2. 创建自定义映射类
通过ClassMap来告诉CsvHelper如何解析原始字段:
using CsvHelper.Configuration; using System.Text.RegularExpressions; public sealed class CompanyLinkMap : ClassMap<CompanyLink> { // 预编译正则,提升性能 private static readonly Regex _hyperlinkRegex = new Regex( @"=HYPERLINK\(""(.*?)""\s*,\s*""(.*?)""\)", RegexOptions.Compiled); public CompanyLinkMap() { // 假设CSV中这个字段的列名为"Link",如果无列名可以用索引(比如GetField<string>(0)) Map(m => m.Url).Convert(args => { var fieldValue = args.Row.GetField<string>("Link"); var match = _hyperlinkRegex.Match(fieldValue); return match.Success ? match.Groups[1].Value.Trim() : null; }); Map(m => m.CompanyName).Convert(args => { var fieldValue = args.Row.GetField<string>("Link"); var match = _hyperlinkRegex.Match(fieldValue); return match.Success ? match.Groups[2].Value.Trim() : null; }); } }
3. 读取并解析CSV
最后用CsvReader加载数据:
using CsvHelper; using System.Globalization; using System.IO; var filePath = "your-company-data.csv"; using (var reader = new StreamReader(filePath)) using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture)) { csv.Context.RegisterClassMap<CompanyLinkMap>(); var companyLinks = csv.GetRecords<CompanyLink>().ToList(); // 这里可以处理拆分后的数据,比如打印验证 foreach (var link in companyLinks) { Console.WriteLine($"URL: {link.Url}, 公司名称: {link.CompanyName}"); } }
方式二:逐行手动解析(适合简单场景)
如果你的需求比较简单,不想定义模型和映射类,也可以直接逐行读取并处理:
using CsvHelper; using System.Globalization; using System.IO; using System.Text.RegularExpressions; var regex = new Regex(@"=HYPERLINK\(""(.*?)""\s*,\s*""(.*?)""\)", RegexOptions.Compiled); var filePath = "your-company-data.csv"; using (var reader = new StreamReader(filePath)) using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture)) { csv.Read(); csv.ReadHeader(); while (csv.Read()) { var rawLinkField = csv.GetField<string>("Link"); var match = regex.Match(rawLinkField); if (match.Success) { var url = match.Groups[1].Value.Trim(); var companyName = match.Groups[2].Value.Trim(); // 在这里处理拆分后的数据 } else { // 处理格式不正确的字段,比如记录日志或设置默认值 } } }
注意事项
- 确保你的CSV字段列名正确,如果没有列名,记得改用字段索引(比如
csv.GetField<string>(0)) - 预编译正则表达式可以提升大量数据的处理性能
- 要考虑字段格式异常的情况,比如匹配失败时返回
null或默认值,避免程序报错 - 别忘了通过NuGet安装CsvHelper:
Install-Package CsvHelper(Package Manager)或dotnet add package CsvHelper(.NET CLI)
内容的提问来源于stack exchange,提问作者John Mackerras
相关产品推荐
相关产品推荐

