Regex.Split将空字符串添加到结果数组中

时间:2012-03-07 11:40:36

标签: c# regex

我有一个正则表达式在简单的逻辑语句中拆分单词运算符和括号(例如“WORD1& WORD2 |(WORd_3&!word_4)”。我提出的正则表达式是“(?[A- Za-z0-9 _] +)|(?[&!\ |()] {1})“。这是一个快速测试程序。


using System; 
using System.Text.RegularExpressions;

namespace ConsoleApplication1 
{ 
    class Program 
    { 
        static void Main(string[] args) 
        { 
        Console.WriteLine("* Test Project *"); 
        string testExpression = "!(LIONV6 | NOT_superCHARGED) &RHD"; 
        string removedSpaces = testExpression.Replace(" ", ""); 
        string[] expectedResults = new string[] { "!", "(", "LIONV6", "|", "NOT_superCHARGED", ")", "&", "RHD" }; 
        string[] splits = Regex.Split(removedSpaces, @"(?[A-Za-z0-9_]+)|(?[&!\|()]{1})");

        Console.WriteLine("Expected\n{0}\nActual\n{1}", expectedResults.AllElements(), splits.AllElements());

        Console.WriteLine("*** Any Key to finish ***");
        Console.ReadKey();
    }
}

public static class Extensions
{
    public static string AllElements(this string[] str)
    {
        string output = "";
        if (str != null)
        {
            foreach (string item in str)
            {
                output += "'" + item + "',";
            }
        }
        return output;
    }
}

正则表达式按照正确的顺序完成了将单词和运算符拆分为数组所需的工作,但结果数组包含许多空元素,我无法弄清楚原因。这不是一个严重的问题,因为我在使用数组时忽略了空元素,但我希望Regex尽可能地完成所有工作,包括忽略空格。

3 个答案:

答案 0 :(得分:2)

试试这个:

string[] splits = Regex.Split(removedSpaces, @"(?[A-Za-z0-9_]+)|(?[&!\|()]{1})").Where(x => x != String.Empty);

答案 1 :(得分:1)

由于分裂的运作方式,空间是jsut。来自help page

  

如果多个匹配彼此相邻,则会在数组中插入空字符串。

作为标准的分裂是将您的比赛作为分隔符。所以实际上返回的标准是相邻匹配之间的很多空字符串(想象一下,如果你在",,,,"上拆分",",你可能会想到的比较,你可能会期望所有的的间隙。

同样来自该帮助页面的是:

  

如果在Regex.Split表达式中使用捕获括号,则为any   捕获的文本包含在结果字符串数组中。

这就是你得到你真正想要的东西的原因。所以它现在有效地向你展示了已经拆分的文本(所有空字符串)以及分隔符。

你正在做的事情可能更好,只需匹配正则表达式(Regex.Match),因为正则表达式中的内容实际上就是你要匹配的内容。

像这样(使用一些linq转换为字符串数组):

Regex.Matches(testExpression, @"([A-Za-z0-9_]+)|([&!\|()]{1})")
     .Cast<Match>()
     .Select(x=>x.Value)
     .ToArray();

请注意,因为这是正匹配,所以不需要先删除空格。

答案 2 :(得分:0)

var matches = Regex.Matches(removedSpaces, @"(\w+|[&!|()])");

foreach (var match in matches)
    Console.Write("'{0}', ", match); // '!', '(', 'LIONV6', '|', 'NOT_superCHARGED', ')', '&', 'RHD', 

实际上,在提取标识符和运算符之前,您不需要删除空格,我建议的正则表达式无论如何都会忽略它们。