如何用管道分隔的字符串(不在双引号内
How to split a string with delimited as pipe (which is not inside double quotes
我有一个如下所示的字符串,它是管道分隔的。它在字符串周围有双引号(例如:"ANI")。
如何用竖线分隔符(不在双引号内)拆分它?
511186|"ANI"|"ABCD-102091474|E|EFG"||"2013-07-20 13:47:19.556"
拆分后的值应该如下所示:
511186
"ANI"
"ABCD-102091474|E|EFG"
"2013-07-20 13:47:19.556"
如有任何帮助,我们将不胜感激!
编辑
我接受的答案不适用于那些内部有双引号的字符串。任何想法,应该是什么问题?
using System.Text.RegularExpressions;
string regexFormat = string.Format(@"(?:^|\{0})(""[^""]*""|[^\{0}]*)", '|');
string[] result = Regex.Matches("111001103|\"E\"|\"BBB\"|\"XXX\"|||10000009|153086649|\"BCTV\"|\"REV\"|||1.00000000|||||\"ABC-BT AD\"|\"\"\"ABC - BT\"\" AD\"|||\"N\"||\"N\"|||\"N\"||\"N",regexFormat)
.Cast<Match>().Select(m => m.Groups[1].Value).ToArray();
foreach(var i in result)
Console.WriteLine(i)
string.Split("|", inputString);
...将为您提供各个部分,但如果任何部分中有管道分隔符,则会失败。
如果它是一个 CSV 文件,遵循所有关于字符转义等的常用 CSV 规则(但使用管道符号而不是逗号),那么您应该考虑使用 CsvHelper,一个 NuGet 包专为读取和写入 CSV 文件而设计。它完成了所有艰苦的工作,并处理了您必须自己处理的所有极端情况。
这是一种方法:
public List<string> Parse(string str)
{
var parts = str.Split(new[] {"|"}, StringSplitOptions.None);
List<string> result = new List<string>();
for (int i = 0; i < parts.Length; i++)
{
string part = parts[i];
if (IsPartStart(part))
{
List<string> sub_parts = new List<string>();
do
{
sub_parts.Add(part);
i++;
part = parts[i];
} while (!IsPartEnd(part));
sub_parts.Add(part);
part = string.Join("|", sub_parts);
}
result.Add(part);
}
return result;
}
private bool IsPartStart(string part)
{
return (part.StartsWith("\"") && !part.EndsWith("\"")) ;
}
private bool IsPartEnd(string part)
{
return (!part.StartsWith("\"") && part.EndsWith("\""));
}
它的工作原理是拆分所有内容,然后通过搜索以 "
开头的部分和以 "
.[=13= 结尾的对应部分来加入一些需要加入的部分]
这是我的做法。它相当简单,我想您会发现它也非常快。我没有 运行 任何测试,但我非常有信心它比正则表达式更快。
IEnumerable<string> Parse(string s)
{
int pos = 0;
while (pos < s.Length)
{
char endChar = '|';
// Test for quoted value
if (s[pos] == '"')
{
pos++;
endChar = '"';
}
// Extract this value
int newPos = s.IndexOf(endChar, pos);
if (newPos < 0)
newPos = s.Length;
yield return s.Substring(pos, newPos - pos);
// Move to start of next value
pos = newPos + 1;
if (pos < s.Length && s[pos] == '|')
pos++;
}
}
您可以使用正则表达式来匹配字符串中的项目:
string[] result = Regex.Matches(s, @"(?:^|\|)(""[^""]*""|[^|]*)")
.Cast<Match>()
.Select(m => m.Groups[1].Value)
.ToArray();
解释:
(?: A non-capturing group
^|\| Matches start of string or a pipe character
) End of group
( Capturing group
"[^"]*" Zero or more non-quotes surrounded by quotes
| Or
[^|]* Zero or more non-pipes
) End of group
我有一个如下所示的字符串,它是管道分隔的。它在字符串周围有双引号(例如:"ANI")。
如何用竖线分隔符(不在双引号内)拆分它?
511186|"ANI"|"ABCD-102091474|E|EFG"||"2013-07-20 13:47:19.556"
拆分后的值应该如下所示:
511186
"ANI"
"ABCD-102091474|E|EFG"
"2013-07-20 13:47:19.556"
如有任何帮助,我们将不胜感激!
编辑
我接受的答案不适用于那些内部有双引号的字符串。任何想法,应该是什么问题?
using System.Text.RegularExpressions;
string regexFormat = string.Format(@"(?:^|\{0})(""[^""]*""|[^\{0}]*)", '|');
string[] result = Regex.Matches("111001103|\"E\"|\"BBB\"|\"XXX\"|||10000009|153086649|\"BCTV\"|\"REV\"|||1.00000000|||||\"ABC-BT AD\"|\"\"\"ABC - BT\"\" AD\"|||\"N\"||\"N\"|||\"N\"||\"N",regexFormat)
.Cast<Match>().Select(m => m.Groups[1].Value).ToArray();
foreach(var i in result)
Console.WriteLine(i)
string.Split("|", inputString);
...将为您提供各个部分,但如果任何部分中有管道分隔符,则会失败。
如果它是一个 CSV 文件,遵循所有关于字符转义等的常用 CSV 规则(但使用管道符号而不是逗号),那么您应该考虑使用 CsvHelper,一个 NuGet 包专为读取和写入 CSV 文件而设计。它完成了所有艰苦的工作,并处理了您必须自己处理的所有极端情况。
这是一种方法:
public List<string> Parse(string str)
{
var parts = str.Split(new[] {"|"}, StringSplitOptions.None);
List<string> result = new List<string>();
for (int i = 0; i < parts.Length; i++)
{
string part = parts[i];
if (IsPartStart(part))
{
List<string> sub_parts = new List<string>();
do
{
sub_parts.Add(part);
i++;
part = parts[i];
} while (!IsPartEnd(part));
sub_parts.Add(part);
part = string.Join("|", sub_parts);
}
result.Add(part);
}
return result;
}
private bool IsPartStart(string part)
{
return (part.StartsWith("\"") && !part.EndsWith("\"")) ;
}
private bool IsPartEnd(string part)
{
return (!part.StartsWith("\"") && part.EndsWith("\""));
}
它的工作原理是拆分所有内容,然后通过搜索以 "
开头的部分和以 "
.[=13= 结尾的对应部分来加入一些需要加入的部分]
这是我的做法。它相当简单,我想您会发现它也非常快。我没有 运行 任何测试,但我非常有信心它比正则表达式更快。
IEnumerable<string> Parse(string s)
{
int pos = 0;
while (pos < s.Length)
{
char endChar = '|';
// Test for quoted value
if (s[pos] == '"')
{
pos++;
endChar = '"';
}
// Extract this value
int newPos = s.IndexOf(endChar, pos);
if (newPos < 0)
newPos = s.Length;
yield return s.Substring(pos, newPos - pos);
// Move to start of next value
pos = newPos + 1;
if (pos < s.Length && s[pos] == '|')
pos++;
}
}
您可以使用正则表达式来匹配字符串中的项目:
string[] result = Regex.Matches(s, @"(?:^|\|)(""[^""]*""|[^|]*)")
.Cast<Match>()
.Select(m => m.Groups[1].Value)
.ToArray();
解释:
(?: A non-capturing group
^|\| Matches start of string or a pipe character
) End of group
( Capturing group
"[^"]*" Zero or more non-quotes surrounded by quotes
| Or
[^|]* Zero or more non-pipes
) End of group