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

本文关键字:结果 数组 添加 字符串 Split Regex | 更新日期: 2023-09-27 18:26:57

我有一个Regex来拆分简单逻辑语句中的单词运算符和括号(例如"WORD1&WORD2|(WORd_3&!WORd_4)"。我想到的Regex是"(?[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完成了将单词和运算符按正确顺序拆分为数组的必要工作,但结果数组包含许多空元素,我不知道为什么。这不是一个严重的问题,因为我只是在使用数组时忽略空元素,但如果可能的话,我希望Regex做所有的工作,包括忽略空格。

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

试试这个:

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

由于拆分的工作方式,空格是jsut。从帮助页面:

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

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

不过,该帮助页面上还有:

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

这就是你在那里得到你真正想要的东西的原因。因此,它现在也向您显示了用分隔符分割的文本(所有空字符串)。

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

类似这样的东西(使用一些linq转换为字符串数组):

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

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

var matches = Regex.Matches(removedSpaces, @"('w+|[&!|()])");
foreach (var match in matches)
    Console.Write("'{0}', ", match); // '!', '(', 'LIONV6', '|', 'NOT_superCHARGED', ')', '&', 'RHD', 

实际上,在提取标识符和运算符之前不需要删除空格,我提出的regex无论如何都会忽略它们。