需要 RegEx 或其他方式来分隔包含转义引号的引用标记
Need RegEx or some other way for separating quoted tokens containing escaped quotes
基本上,我的任务是解析这个命令行:
-p "This is a string ""with quotes""" d:.txt "d:\some folder.out"
我需要的是将这个字符串拆分成:
- -p
- 这是一个字符串"with quotes"
- d:\1.txt
- d:\some folder.out
我进行了搜索(是的,我确实进行了搜索),但我发现的所有示例要么没有包含转义引号,要么使用 \" 作为转义符号。
我会改用真正的 csv 解析器,例如 .NET 中唯一可用的解析器:
string str = "-p \"This is a string \"\"with quotes\"\"\" d:\1.txt \"d:\some folder\1.out\"";
var allLineFields = new List<string[]>();
using (var parser = new Microsoft.VisualBasic.FileIO.TextFieldParser(new StringReader(str)))
{
parser.Delimiters = new string[] { " " };
parser.HasFieldsEnclosedInQuotes = true; // <--- !!!
string[] lineFields;
while ((lineFields = parser.ReadFields()) != null)
{
allLineFields.Add(lineFields);
}
}
对于您的示例字符串,列表包含一个 string[]
和您的四个标记:
-p
This is a string "with quotes"
d:.txt
d:\some folder.out
使用正则表达式(如果你坚持不使用 Tim Schmelter 的建议的解析器),这样的东西应该可以工作(它匹配给定的字符串,但我不能保证它是完全防弹的):
((?:"(?:[^"]|"")*")|\S+)
将其分解,您正在分组:
- 引号
"
后跟非引号 ^"
或两个引号 ""
,后跟引号 "
- 一堆(一个或多个)非space字符
\S
请参阅 here 来尝试一下。
手写版:
private static string[] ParseArguments(string text)
{
if (string.IsNullOrWhiteSpace(text)) return new string[0];
var entries = new List<string>(8);
var stringBuilder = new StringBuilder(64);
var inString = false;
var l = text.Length;
for (var i = 0; i < l; i++)
{
var c = text[i];
if (inString)
{
if (c == '"')
{
if (i != l - 1 && text[i + 1] == '"')
{
stringBuilder.Append(c);
i++;
}
else inString = false;
}
else stringBuilder.Append(c);
}
else if (c == '"') inString = true;
else if (char.IsWhiteSpace(c))
{
if (stringBuilder.Length == 0) continue;
entries.Add(stringBuilder.ToString());
stringBuilder.Length = 0;
}
else stringBuilder.Append(c);
}
if (stringBuilder.Length != 0) entries.Add(stringBuilder.ToString());
return entries.ToArray();
}
基本上,我的任务是解析这个命令行:
-p "This is a string ""with quotes""" d:.txt "d:\some folder.out"
我需要的是将这个字符串拆分成:
- -p
- 这是一个字符串"with quotes"
- d:\1.txt
- d:\some folder.out
我进行了搜索(是的,我确实进行了搜索),但我发现的所有示例要么没有包含转义引号,要么使用 \" 作为转义符号。
我会改用真正的 csv 解析器,例如 .NET 中唯一可用的解析器:
string str = "-p \"This is a string \"\"with quotes\"\"\" d:\1.txt \"d:\some folder\1.out\"";
var allLineFields = new List<string[]>();
using (var parser = new Microsoft.VisualBasic.FileIO.TextFieldParser(new StringReader(str)))
{
parser.Delimiters = new string[] { " " };
parser.HasFieldsEnclosedInQuotes = true; // <--- !!!
string[] lineFields;
while ((lineFields = parser.ReadFields()) != null)
{
allLineFields.Add(lineFields);
}
}
对于您的示例字符串,列表包含一个 string[]
和您的四个标记:
-p
This is a string "with quotes"
d:.txt
d:\some folder.out
使用正则表达式(如果你坚持不使用 Tim Schmelter 的建议的解析器),这样的东西应该可以工作(它匹配给定的字符串,但我不能保证它是完全防弹的):
((?:"(?:[^"]|"")*")|\S+)
将其分解,您正在分组:
- 引号
"
后跟非引号^"
或两个引号""
,后跟引号"
- 一堆(一个或多个)非space字符
\S
请参阅 here 来尝试一下。
手写版:
private static string[] ParseArguments(string text)
{
if (string.IsNullOrWhiteSpace(text)) return new string[0];
var entries = new List<string>(8);
var stringBuilder = new StringBuilder(64);
var inString = false;
var l = text.Length;
for (var i = 0; i < l; i++)
{
var c = text[i];
if (inString)
{
if (c == '"')
{
if (i != l - 1 && text[i + 1] == '"')
{
stringBuilder.Append(c);
i++;
}
else inString = false;
}
else stringBuilder.Append(c);
}
else if (c == '"') inString = true;
else if (char.IsWhiteSpace(c))
{
if (stringBuilder.Length == 0) continue;
entries.Add(stringBuilder.ToString());
stringBuilder.Length = 0;
}
else stringBuilder.Append(c);
}
if (stringBuilder.Length != 0) entries.Add(stringBuilder.ToString());
return entries.ToArray();
}