如何修复这个正则表达式?
Posted
技术标签:
【中文标题】如何修复这个正则表达式?【英文标题】:How can I fix this regex expression? 【发布时间】:2020-05-03 15:42:14 【问题描述】:前言:这个问题是this question的派生题。
Here is my code:
using System;
using System.Linq;
using System.Text.RegularExpressions;
class MainClass
public static void Main (string[] args)
const string rawLine = "\"TeamName\",\"PlayerName\",\"Position\" \"Chargers\",\"Philip Rivers\",\"QB\" \"Colts\",\"Peyton Manning\",\"QB\" \"Patriots\",\"Tom Brady\",\"QB\"";
var parsedLines = Regex.Split(rawLine, "(\".*? \"(?:,\".*? \")*)");
parsedLines.ToList().ForEach(Console.WriteLine);
Console.WriteLine("Press [ENTER] to exit.");
Console.ReadLine();
这是我的输出:
"TeamName","PlayerName","Position" "
Chargers
","Philip Rivers","QB" "
Colts
","Peyton Manning","QB" "
Patriots","Tom Brady","QB"
Press [ENTER] to exit.
这是我想要的输出:
"TeamName","PlayerName","Position"
"Chargers","Philip Rivers","QB"
"Colts","Peyton Manning","QB"
"Patriots","Tom Brady","QB"
Press [ENTER] to exit.
如何修复正则表达式以生成我想要的输出?
相关:
line breaks lost in sql server How do you view ALL text from an ntext or nvarchar(max) in SSMS?【问题讨论】:
我强烈建议您使用 CSVHelper 而不是正则表达式,除非您确定 CSV 不会包含嵌入/转义引号或逗号之类的内容。 CSV 是一种非常灵活的格式。它甚至不必用逗号分隔即可成为 CSV。 @Amy 我不熟悉 CSVHelper,但我很熟悉。能否请您描述一个使用 CSVHelper 的解决方案? 我已经很久没有需要它的服务了(过去几年没有 CSV :o),但我记得他们的文档相当不错。见joshclose.github.io/CsvHelper/getting-started。 或者甚至可以用"\"\n\""
或任何你想要的换行符替换"\" \""
。
除非 CSVHelper 有办法指定 record 分隔符,否则它不会有任何帮助。上一个问题的答案(已删除)提到了 CSVHelper 配置的 Delimiter
属性,但那是 field 分隔符(这就是它被删除的原因)。我找不到记录分隔符选项(但这并不意味着没有)。那里的另一个答案提到了在两个空格和quote-space-space-quote上的拆分,所以人们希望在转向正则表达式然后发布这个问题之前已经探索过。
【参考方案1】:
使用否定的lookbehind、肯定的lookbehind、带量词的字符类、肯定的lookahead 和否定的lookahead。
Working Demo
using System;
using System.Linq;
using System.Text.RegularExpressions;
class MainClass
public static void Main (string[] args)
const string rawLine = "\"TeamName\",\"PlayerName\",\"Position\" \"Chargers\",\"Philip Rivers\",\"QB\" \"Colts\",\"Peyton Manning\",\"QB\" \"Patriots\",\"Tom Brady\",\"QB\"";
var parsedLines = Regex.Split(rawLine, "(?<![,])(?<=[\"])[ ]2(?=[\"])(?![,])");
parsedLines.ToList().ForEach(Console.WriteLine);
Console.WriteLine("Press [ENTER] to exit.");
Console.ReadLine();
【讨论】:
【参考方案2】:正如 Amy 已经提到的,您的字符串似乎类似于 CSV。如果它确实是有效的 CSV - 请使用特殊库。
如果 CSVHelper 在这种情况下不适用并且您确实需要正则表达式,请尝试以下操作:
(?<=(?:^| ))(.*?)(?=(?: \")|$)
我没有为 C# 编码,因此由于 c# 特定,正则表达式可能需要一些编辑。
编辑。代码示例。
using System;
using System.Linq;
using System.Text.RegularExpressions;
class MainClass
public static void Main (string[] args)
const string rawLine = "\"TeamName\",\"PlayerName\",\"Position\" \"Chargers\",\"Philip Rivers\",\"QB\" \"Colts\",\"Peyton Manning\",\"QB\" \"Patriots\",\"Tom Brady\",\"QB\"";
//var parsedLines = Regex.Split(rawLine, "(?<=(?:^| ))(.*?)(?=(?: \")|$)");
var parsedLines = Regex.Split(rawLine, "(?<=^)(.*?)(?=(?: \")|$)|(?<= )(.*?)(?=(?: \")|$)");
parsedLines.ToList().ForEach(Console.WriteLine);
Console.WriteLine("Press [ENTER] to exit.");
Console.ReadLine();
此代码带有“脏”修复断言错误。但是,我无法使用 onlinetool 复制它:) 此示例中注释的原始正则表达式。
我希望这会对你有所帮助。但我必须再说一遍,如果你使用 csv - 最好使用特殊工具,而不是正则表达式 :)
【讨论】:
您可以使用 dotnetfiddle 或 regexstorm 在 c# 中测试正则表达式。 哎呀,谢谢。我错过了我可以在您提供的 repl.it 链接上进行测试。正则表达式她似乎很好。但是如果 C# 出现断言错误 - 我们可以尝试“脏”修复。我现在就编辑我的帖子。【参考方案3】:贯穿整个线程的优秀 cmets(我强烈建议采用其中一种选择),我不会专注于它们。这是一个替代解决方案,它使用Regex
模式中的Matches
,skip
你有多少字段(列),然后take
你想要多少记录。
我正在使用(\"(.*?)[^,]")
之类的模式,可以在here 中找到其含义的解释。
const string rawLine = "\"TeamName\",\"PlayerName\",\"Position\" \"Chargers\",\"Philip Rivers\",\"QB\" \"Colts\",\"Peyton Manning\",\"QB\" \"Patriots\",\"Tom Brady\",\"QB\"";
var matches = new Regex(@"(\""(.*?)[^,]"")").Matches(rawLine).Cast<Match>().ToList();
// loop through our matches
for(int i = 0; i < matches.Count; i++)
// join our records we need to output
string str = string.Join(",", matches.Skip(i * 3).Take(3));
if(!string.IsNullOrEmpty(str))
Console.WriteLine(str);
Console.WriteLine("Press [ENTER] to exit.");
Console.ReadLine();
请注意,根本没有错误检查,可以改进,但会产生您需要的输出。 *还要确保导入System.Linq
(如果还没有)。
输出测试
【讨论】:
以上是关于如何修复这个正则表达式?的主要内容,如果未能解决你的问题,请参考以下文章
如何修复 jsx 结束标签上的 linting 错误:“未关闭的正则表达式”?