C# 正则表达式匹配大小写 - 拆分字符串并写入文件输出
C# Regex match case - split string and write to file output
基本上我有一个这种格式的记录文本文件:
(1909, 'Ford', 'Model T'),
(1926, 'Chrysler', 'Imperial'),
(1948, 'Citroën', '2CV'),
我要输出到如下格式的文本文件
new Vehicle() { Id = 1, Year = 1909, Make = "Ford", Model = "Model T" },
new Vehicle() { Id = 2, Year = 1926, Make = "Chrysler", Model = "Imperial" },
new Vehicle() { Id = 3, Year = 1948, Make = "Citroën", Model = "2CV" },
我知道我需要将每一行分成相关的文本部分,例如试图遵循类似 this SO 的问题。但是在如何获取年份、品牌和型号的相关匹配字符串部分方面遇到了障碍。
到目前为止我已经找到了这个,它找到了括号之间的所有内容:
\(([^()]+)\)
但不确定如何将值分组并用逗号分隔:
非常感谢任何帮助。
为什么不使用 string.Split(',')?会比 Regex 更快并且适合您(当然,首先删除每行的最后一个 ','。
将它们分组的正则表达式:
\((\d+),\s+[']([\w\së]+)['],\s+[']([\w\s]+)[']\)[,]*
请注意 Citroën 有问题 => 您必须输入所有不在 a-z、A-Z 内的特殊符号(如 ë ü ÿ 等..)
要在代码中使用,您将获得第一组:
string cars = @"(1909, 'Ford', 'Model T'),"
string pattern = @"\((\d+),\s+[']([\w\së]+)['],\s+[']([\w\s]+)[']\)[,]*";
var lResult = Regex.Match(cars, pattern);
if(lResult.Success)
foreach( var iGroup in lResult.Groups)
Console.WriteLine(iGroup);
在lResult.Groups你得到了关于汽车的信息,你只是根据需要将它输出到文件中。
C# 6.0:
Console.WriteLine($"new Vehicle() {{ Id = 1, Year = {lResults.Groups[1]}, Make = \"{lResults.Groups[2]}\", Model = \"{lResults.Groups[3]}\"}},");
旧语法:
Console.WriteLine(@"new Vehicle() { Id = 1, Year = "+ lMatch.Groups[1]+", Make = "+ lMatch.Groups[2] + ", Model = "+ lMatch.Groups[3] + " },");
一旦你将其自动化到 for 循环中,你就可以轻松添加 Id。
我的示例在 Groups[0] 中有整个字符串,所以这就是为什么我的索引从 1 开始到 3。
正如@Toto所说,\w
已经包含了\d
,那就不用写了。
如果您愿意使用解析器框架(这可能有点矫枉过正),您可以使用例如 sprache
。没有适当错误处理的示例:
Parser<string> stringContent =
from open in Parse.Char('\'').Once()
from content in Parse.CharExcept('\'').Many().Text()
from close in Parse.Char('\'').Once()
select content;
Parser<string> numberContent = Parse.Digit.AtLeastOnce().Text();
Parser<string> element = stringContent.XOr(numberContent);
Parser<List<string>> elements =
from e in element.DelimitedBy(Parse.Char(',').Token())
select e.ToList();
Parser<List<string>> parser =
from open in Parse.Char('(').Once()
from content in elements
from close in Parse.Char(')').Once()
select content;
var input = new List<string> { "(1909, 'Ford', 'Model T')", "(1926, 'Chrysler', 'Imperial')", "(1948, 'Citroën', '2CV')" };
foreach (var line in input)
{
var parsed = parser.Parse(line);
var year = Int32.Parse(parsed[0]);
var make = parsed[1];
var model = parsed[2];
Console.WriteLine(">> " + year + " " + make + " " + model);
}
您可以根据命名的捕获组使用此代码段:
var cars = new List<string>() {
"(1909, 'Ford', 'Model T')",
"(1926, 'Chrysler', 'Imperial')",
"(1948, 'Citroën', '2CV')",
};
var regex = @"(?<Year>\d+).*?'(?<Brand>.*?)'.*?'(?<Model>.*?)'";
foreach (var car in cars)
{
var match = Regex.Match(car, regex);
if (match.Success)
{
Console.WriteLine($"{match.Groups["Brand"]} make {match.Groups["Model"]} in {match.Groups["Year"]}");
}
}
将打印:
Ford make Model T in 1909
Chrysler make Imperial in 1926
Citroën make 2CV in 1948
基本上我有一个这种格式的记录文本文件:
(1909, 'Ford', 'Model T'),
(1926, 'Chrysler', 'Imperial'),
(1948, 'Citroën', '2CV'),
我要输出到如下格式的文本文件
new Vehicle() { Id = 1, Year = 1909, Make = "Ford", Model = "Model T" },
new Vehicle() { Id = 2, Year = 1926, Make = "Chrysler", Model = "Imperial" },
new Vehicle() { Id = 3, Year = 1948, Make = "Citroën", Model = "2CV" },
我知道我需要将每一行分成相关的文本部分,例如试图遵循类似 this SO 的问题。但是在如何获取年份、品牌和型号的相关匹配字符串部分方面遇到了障碍。
到目前为止我已经找到了这个,它找到了括号之间的所有内容:
\(([^()]+)\)
但不确定如何将值分组并用逗号分隔:
非常感谢任何帮助。
为什么不使用 string.Split(',')?会比 Regex 更快并且适合您(当然,首先删除每行的最后一个 ','。
将它们分组的正则表达式:
\((\d+),\s+[']([\w\së]+)['],\s+[']([\w\s]+)[']\)[,]*
请注意 Citroën 有问题 => 您必须输入所有不在 a-z、A-Z 内的特殊符号(如 ë ü ÿ 等..)
要在代码中使用,您将获得第一组:
string cars = @"(1909, 'Ford', 'Model T'),"
string pattern = @"\((\d+),\s+[']([\w\së]+)['],\s+[']([\w\s]+)[']\)[,]*";
var lResult = Regex.Match(cars, pattern);
if(lResult.Success)
foreach( var iGroup in lResult.Groups)
Console.WriteLine(iGroup);
在lResult.Groups你得到了关于汽车的信息,你只是根据需要将它输出到文件中。
C# 6.0:
Console.WriteLine($"new Vehicle() {{ Id = 1, Year = {lResults.Groups[1]}, Make = \"{lResults.Groups[2]}\", Model = \"{lResults.Groups[3]}\"}},");
旧语法:
Console.WriteLine(@"new Vehicle() { Id = 1, Year = "+ lMatch.Groups[1]+", Make = "+ lMatch.Groups[2] + ", Model = "+ lMatch.Groups[3] + " },");
一旦你将其自动化到 for 循环中,你就可以轻松添加 Id。
我的示例在 Groups[0] 中有整个字符串,所以这就是为什么我的索引从 1 开始到 3。
正如@Toto所说,\w
已经包含了\d
,那就不用写了。
如果您愿意使用解析器框架(这可能有点矫枉过正),您可以使用例如 sprache
。没有适当错误处理的示例:
Parser<string> stringContent =
from open in Parse.Char('\'').Once()
from content in Parse.CharExcept('\'').Many().Text()
from close in Parse.Char('\'').Once()
select content;
Parser<string> numberContent = Parse.Digit.AtLeastOnce().Text();
Parser<string> element = stringContent.XOr(numberContent);
Parser<List<string>> elements =
from e in element.DelimitedBy(Parse.Char(',').Token())
select e.ToList();
Parser<List<string>> parser =
from open in Parse.Char('(').Once()
from content in elements
from close in Parse.Char(')').Once()
select content;
var input = new List<string> { "(1909, 'Ford', 'Model T')", "(1926, 'Chrysler', 'Imperial')", "(1948, 'Citroën', '2CV')" };
foreach (var line in input)
{
var parsed = parser.Parse(line);
var year = Int32.Parse(parsed[0]);
var make = parsed[1];
var model = parsed[2];
Console.WriteLine(">> " + year + " " + make + " " + model);
}
您可以根据命名的捕获组使用此代码段:
var cars = new List<string>() {
"(1909, 'Ford', 'Model T')",
"(1926, 'Chrysler', 'Imperial')",
"(1948, 'Citroën', '2CV')",
};
var regex = @"(?<Year>\d+).*?'(?<Brand>.*?)'.*?'(?<Model>.*?)'";
foreach (var car in cars)
{
var match = Regex.Match(car, regex);
if (match.Success)
{
Console.WriteLine($"{match.Groups["Brand"]} make {match.Groups["Model"]} in {match.Groups["Year"]}");
}
}
将打印:
Ford make Model T in 1909
Chrysler make Imperial in 1926
Citroën make 2CV in 1948