我正在使用以下正则表达式进行标记:
reg = new Regex("([ \\t{}%$^&*():;_–`,\\-\\d!\"?\n])");
正则表达式应该在以后过滤掉所有内容,但是我遇到问题的输入字符串格式是以下形式:
; "string1"; "string2"; "string...n";
字符串的结果:; "social life"; "city life"; "real life"
我知道应该如下:
; White " social White life " ; White " city White life " ; White " real White life "
然而,有一个问题,我得到以下形式的输出
; empty White empty " social White life " empty ; empty White empty " city White life " empty ; empty White empty " real White life " empty
白色:意为白色空间, empty:表示拆分数组中的空条目。
我的拆分代码如下:
string[] ret = reg.Split(input);
for (int i = 0; i < ret.Length; i++)
{
if (ret[i] == "")
Response.Write("empty<br>");
else
if (ret[i] == " ")
Response.Write("White<br>");
else
Response.Write(ret[i] + "<br>");
}
为什么我会收到这些空条目?特别是当;
后跟空格后跟"
时,结果如下所示:
; empty White empty "
我能解释为什么命令会添加空条目吗?以及如何在没有任何额外的O(n)复杂性或使用其他数据结构ret
答案 0 :(得分:1)
根据我的经验,在正则表达式比赛中分裂几乎总是不是最好的主意。通过简单匹配,您将获得更好的结果。
正则表达式非常适合于标记化目的,因为它们可以让您轻松实现状态机,只需看一下:
\G(?:
(?<string> "(?>[^"\\]+|\\.)*" )
| (?<separator> ; )
| (?<whitespace> \s+ )
| (?<invalid> . )
)
Demo - 当然使用RegexOptions.IgnorePatternWhitespace
。
此处,每场比赛将具有以下属性:
whitespace
群组,如果您遇到匹配的invalid
群组,则应该提出错误。 string
组将匹配整个带引号的字符串,它可以处理字符串中的\"
之类的转义。
invalid
组应始终位于模式的最后。您可以为其他类型添加规则。
一些示例代码:
var regex = new Regex(@"
\G(?:
(?<string> ""(?>[^""\\]+|\\.)*"" )
| (?<separator> ; )
| (?<whitespace> \s+ )
| (?<invalid> . )
)
", RegexOptions.IgnorePatternWhitespace);
var input = "; \"social life\"; \"city life\"; \"real life\"";
var groupNames = regex.GetGroupNames().Skip(1).ToList();
foreach (Match match in regex.Matches(input))
{
var groupName = groupNames.Single(name => match.Groups[name].Success);
var group = match.Groups[groupName];
Console.WriteLine("{0}: {1}", groupName, group.Value);
}
这会产生以下结果:
separator: ;
whitespace:
string: "social life"
separator: ;
whitespace:
string: "city life"
separator: ;
whitespace:
string: "real life"
看看处理这些结果比使用拆分更容易吗?