2012-03-07 65 views
3

我有一个正则表达式可以在简单的逻辑语句中分割出单词运算符和括号(例如“WORD1 & WORD2 |(WORd_3 &!word_4)”。我提出的正则表达式是 “([A-ZA-Z0-9 _] +?)|(?[& \ |!(){1})” 这里是一个快速测试程序Regex.Split在结果数组中添加空字符串


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; 
    } 
} 

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

+0

你在哪里期待输入字符串中的空格去?你没有他们在你预期的阵列,但我不知道你在哪里摆脱他们在任何地方... – Chris 2012-03-07 12:04:25

+1

@Chris没有空格,他用testExpression.Replace(“”,“”); – 2012-03-07 12:11:22

+0

@DorCohen:啊,我真想知道我是否在密集。看起来我是。;-) – Chris 2012-03-07 12:13:30

回答

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

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

其实,你并不需要提取的标识符和运营商之前删除的空间,我提出的正则表达式无论如何都会忽略它们。

2

试试这个:

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

upvoted良好的横向思维,但正则表达式实际上并没有这样做。 – 2012-03-07 12:22:04

1

由于分割工作的方式,空间很小。来自help page

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

什么拆分标准是把你的比赛作为分隔符。因此实际上,将返回的标准是相邻匹配之间的很多空字符串(想象一下,如果您将",,,,"分割为",",那么您可能会预期所有空位。这种帮助页面,虽然是:

如果捕获括号在一个Regex.Split表达式中使用,任何 捕获文本包含得到的字符串数组中

这是你做了什么的原因。你真的想要进来在那里。因此,它现在正在向您显示使用分隔符分隔的文本(所有空字符串)。

因为正则表达式中的内容实际上是您想要匹配的内容,所以您所做的只是匹配正则表达式(与Regex.Match)可能会更好。

这样的事情(使用一些LINQ转换为字符串数组):

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

注意,因为这是采取积极的比赛并不需要的空间将被首先删除。

+0

感谢您的完整解释。我已经去了匹配的想法。 – 2012-03-07 12:50:48