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做所有的工作,包括忽略空格。
试试这个:
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无论如何都会忽略它们。