如何将空格(除引号内的空格)转换为C#中的逗号?
假设我有一个这样的字符串:如何将空格(除引号内的空格)转换为C#中的逗号?
one two three "four five six" seven eight
,我想将它转化成这样:
one,two,three,"four five six",seven,eight
是什么在C#中要做到这一点最简单的方法?
下面是我想出了一个更可重复使用的功能:
private string ReplaceWithExceptions(string source, char charToReplace,
char replacementChar, char exceptionChar)
{
bool ignoreReplacementChar = false;
char[] sourceArray = source.ToCharArray();
for (int i = 0; i < sourceArray.Length; i++)
{
if (sourceArray[i] == exceptionChar)
{
ignoreReplacementChar = !ignoreReplacementChar;
}
else
{
if (!ignoreReplacementChar)
{
if (sourceArray[i] == charToReplace)
{
sourceArray[i] = replacementChar;
}
}
}
}
return new string(sourceArray);
}
用法:
string test = "one two three \"four five six\" seven eight";
System.Diagnostics.Debug.WriteLine(ReplaceWithExceptions(test, char.Parse(" "),
char.Parse(","), char.Parse("\"")));
我会使用Regex类来达到这个目的。
正则表达式可以用来匹配你的输入,将它分解成单独的组,然后你可以重新组合,但是你想要的。你可以在regex classes here上找到相关文件。
Regex rx = new Regex("(\w)|([\"]\w+[\"])");
MatchCollection matches = rx.Matches("first second \"third fourth fifth\" sixth");
string.Join(", ", matches.Select(x => x.Value).ToArray());
假设引号是不可避免的,您可以执行以下操作。
public string SpaceToComma(string input) {
var builder = new System.Text.StringBuilder();
var inQuotes = false;
foreach (var cur in input) {
switch (cur) {
case ' ':
builder.Append(inQuotes ? cur : ',');
break;
case '"':
inQuotes = !inQuotes;
builder.Append(cur);
break;
default:
builder.Append(cur);
break;
}
}
return builder.ToString();
}
static string Space2Comma(string s)
{
return string.Concat(s.Split('"').Select
((x, i) => i % 2 == 0 ? x.Replace(' ', ',') : '"' + x + '"').ToArray());
}
我的第一个猜测是使用已经写了一个解析器和简单的改变分隔符和引号字符满足您的需求(这是和「)。
它看起来像这样可用您在C#: http://msdn.microsoft.com/en-us/library/microsoft.visualbasic.fileio.textfieldparser.aspx
或许,如果你更改为“”,它可能会满足您的需求在文件中读取分隔符,那么它只是一个调用的string.join()一每一行的事
这可能是矫枉过正,但如果你认为这个问题可以概括,如具有必要被其他类型的字符分割,或者有额外的定义令牌的规则,您应该考虑使用解析器生成器(如Coco)或自行编写一个简单的。例如,Coco/R将根据您提供的EBNF语法生成一个词法分析器和分析器。词法分析器将是DFA或状态机,它是由JaredPar提供的代码的一般形式。对于可可/ R你的语法定义是这样的:
CHARACTERS
alphanum = 'A'..'Z' + 'a'..'z' + '0'..'9'.
TOKENS
unit = '"' {alphanum|' '} '"' | {alphanum}.
随后将所得词法分析器将扫描和相应tokanize输入。
根据我对原始问题的评论,如果你不需要最终结果中的引号,这将完成工作。如果你做需要报价,随时忽略这一点。
private String SpaceToComma(string input)
{
String[] temp = input.Split(new Char[] { '"' }, StringSplitOptions.RemoveEmptyEntries);
for (Int32 i = 0; i < temp.Length; i += 2)
{
temp[i] = temp[i].Trim().Replace(' ', ',');
}
return String.Join(",", temp);
}
@Mehrdad打我,但想无论如何,我会张贴:
static string Convert(string input)
{
var slices = input
.Split('"')
.Select((s, i) => i % 2 != 0
? @"""" + s + @""""
: s.Trim().Replace(' ', ','));
return string.Join(",", slices.ToArray());
}
LINQified和测试,:-) ......对于一个完整的控制台应用程序:http://pastebin.com/f23bac59b
你真的想要报价出现在最终的输出?在他们出现的时候,你不能用逗号分割结果字符串来对每个项目进行进一步的处理。 – JeffK 2009-06-19 21:14:49
@JeffK:对于这个特定的应用程序,“四五六”被认为是一个单一的项目。 – raven 2009-06-19 23:13:29
对,但你需要它有周围的报价。换句话说,以下哪一项是您想要的结果? 一,二,三,“四五六”,七,八 > 一,二,三,四五六,七,八 我的问题是你是否真的想要的第一个结果。这些引用对我后来的处理来说似乎是一个问题;在使用该行之前,您不需要删除它们吗? – JeffK 2009-06-20 01:27:07