【发布时间】:2010-06-22 17:23:05
【问题描述】:
我想说一串话:
Guiness Harp "Holy Moses"
这样在 C# 或 VB 中得到一个匹配集:
Guiness
Harp
Holy Moses
基本上它在空格上拆分,除非空格周围有引号,然后引号之间的那些词被视为一个短语。
谢谢, 凯文
【问题讨论】:
我想说一串话:
Guiness Harp "Holy Moses"
这样在 C# 或 VB 中得到一个匹配集:
Guiness
Harp
Holy Moses
基本上它在空格上拆分,除非空格周围有引号,然后引号之间的那些词被视为一个短语。
谢谢, 凯文
【问题讨论】:
如果引用的字符串中没有任何(转义或双引号)引号,则可以搜索
"[^"]*"|\S+
但是,引号将成为匹配的一部分。如有必要,可以扩展正则表达式以处理带引号的字符串中的引号。
另一种(在这种情况下更可取)的可能性是使用 csv 解析器。
例如(Python):
import csv
reader = csv.reader(open('test.txt'), delimiter=' ', quotechar='"')
for row in reader:
print(row)
【讨论】:
这是另一种方法:
string s0 = @"Guiness Harp ""Holy Moses""";
Regex r = new Regex(@"""(?<FIELD>[^""]*)""|(?<FIELD>\S+)");
foreach (Match m in r.Matches(s0))
{
Console.WriteLine(m.Groups["FIELD"].Value);
}
这利用了 .NET 正则表达式允许您在同一个正则表达式中重用组名这一事实。很少有正则表达式允许这样做,而其中只有 Perl 6 与 .NET 一样灵活。
【讨论】:
正则表达式不能计数,导致分隔符解析困难。
我会为此使用解析器而不是正则表达式。
【讨论】:
如果这是一个简单的解析,您也许可以修剪开始和结束的引号。
string text = "Guiness Harp \"Holy Moses\"";
string pattern = @"""[^""]*""|\S+";
MatchCollection matches = Regex.Matches( text, pattern );
foreach( Match match in matches )
{
string value = match.Value.Trim( '"' );
Console.Out.WriteLine( value );
}
但是,这种实现方式不是很灵活。我只会在内部工具中使用这样的东西。或者你不介意扔掉你的代码。
【讨论】: