此主题非常类似于我想要的内容:Regular Expression to split on spaces unless in quotes
但我需要一些我无法弄清楚的额外规则: - 上面的线程会在空格上分割,除非它们是双引号。但是,它也会在标点符号上分开。我需要双引号内的任何东西保持为一个整体。
例如:
/更新设置0值=“新值”/保存应返回
/更新
setting0
值=
新值(我不在乎是否修剪报价)
/保存
/导入“C:\ path \ file.xml”“C:\ path_2 \ file_2.xml”/退出应该返回
/导入
C:\ path \ file.xml (我不在乎是否关闭引号)
C:\ PATH_2 \ file_2.xml
/退出
我最终在上面的帖子中使用了这个表达式:
(?<=")\w[\w\s]*(?=")|\w+|"[\w\s]*"
有人可以帮我调整一下吗?谢谢!
答案 0 :(得分:3)
我没有在C#中尝试过,而是在Excel中使用VBA,但它可能会有所帮助。我也改变了双重单引号。无论如何,这是正则表达式
文本:
/更新设置0值='新值'/保存
正则表达式:
('{1}(\w|\s|:|\\|\.)+'{1}|\w)+
结果:
<强>更新强>
<强> setting0 强>
<强>值强>
'新值'
保存强>
文本:
/导入'C:\ path \ file.xml''C:\ path_2 \ file_2.xml'/退出
结果:
导入强>
<强> 'C:\路径\ file.xml'强>
<强> 'C:\ PATH_2 \ file_2.xml'强>
退出强>
答案 1 :(得分:0)
这是一个通常无法使用正则表达式解决的问题。相反,你可以编写一个简单的解析器,它接受一行,读取每个字符,然后当它遇到一个空格而不是在一个引号内时,它会获取当前的子字符串并将其添加到列表中:
public static string[] ParseLine(string line)
{
var insideQuotes = false;
var parts = new List<string>();
var j = 0;
for (var i = 0; i < line.Length; i++)
{
switch (line[i])
{
case '"':
insideQuotes = !insideQuotes;
break;
case ' ':
if (!insideQuotes)
{
parts.Add(line.Substring(j, i - j));
j = i + 1;
}
break;
default:
continue;
}
}
return parts.ToArray();
}
但请注意,这不会像引号内的转义引号一样处理。
答案 2 :(得分:0)
如果偶数个双引号且没有转义引号,则此方法有效:
^
\s*
(?:
(?:
([^\s"]+)
|
"([^"]*)"
)
\s*
)+
$
答案 3 :(得分:0)
var matches = Regex.Matches("/Update setting0 value=\"new value\" /Save", "\\G(?:(\"[^\"]*\"?|[^ \"]+)|[ ]+)");
foreach (Match match in matches) {
foreach (Capture capture in match.Groups[1].Captures) {
Console.WriteLine(capture);
}
}
如果您不想使用引号("new value"
变为new value
)
var matches = Regex.Matches("/Update setting0 value=\"new value\" /Save", "\\G(?:\"(?<1>[^\"]*)\"?|(?<1>[^ \"]+)|[ ]+)");
第二个?
之后的\"
是要捕获未公开的引号。
答案 4 :(得分:0)
只是eulerfx
发布的修改版本。这一个:
应该产生原始问题中要求的结果(“主题”也是如此)。
结果中不包含引号
仅在结果中不包含空格
在任何不在引号内的空格上分割结果
通过添加循环后留下的任何内容来处理缺少的结束引用
修剪结果,除非在引号内。
我主要是为了解析IMAP列表结果的每一行的最后两部分。
public static string[] ParseLine(string line)
{
var insideQuotes = false;
var start = -1;
var parts = new List<string>();
for (var i = 0; i < line.Length; i++)
{
if (Char.IsWhiteSpace(line[i]))
{
if (!insideQuotes)
{
if (start != -1)
{
parts.Add(line.Substring(start, i - start));
start = -1;
}
}
}
else if (line[i] == '"')
{
if (start != -1)
{
parts.Add(line.Substring(start, i - start));
start = -1;
}
insideQuotes = !insideQuotes;
}
else
{
if (start == -1)
start = i;
}
}
if (start != -1)
parts.Add(line.Substring(start));
return parts.ToArray();
}