正则expression式除非在引号中分隔空格

我想使用.Net Regex.Split方法将这个inputstring拆分成一个数组。 除非用引号括起来,否则它必须以空格分隔。

input:这是“我的string”它有“六个匹配”

预期产出:

  1. 这里
  2. 我的string
  3. 具有
  4. 六场比赛

我需要什么样的模式? 我也需要指定任何RegexOptions?

没有选项要求

正则expression式:

\w+|"[\w\s]*" 

C#:

 Regex regex = new Regex(@"\w+|""[\w\s]*"""); 

或者,如果您需要排除“字符:

  Regex .Matches(input, @"(?<match>\w+)|\""(?<match>[\w\s]*)""") .Cast<Match>() .Select(m => m.Groups["match"].Value) .ToList() .ForEach(s => Console.WriteLine(s)); 

列文的解决scheme大部分都在那里,正如他在评论中所说的那样,只是把结局改为巴尔泰克的解决scheme。 最终的结果是以下工作regEx:

 (?<=")\w[\w\s]*(?=")|\w+|"[\w\s]*" 

input:这是“我的string”它有“六个匹配”

输出:

  1. 这里
  2. “我的串”
  3. 具有
  4. “六场比赛”

不幸的是它包括引号。 如果您改为使用以下内容:

 (("((?<token>.*?)(?<!\\)")|(?<token>[\w]+))(\s)*) 

并明确捕捉“标记”匹配如下:

  RegexOptions options = RegexOptions.None; Regex regex = new Regex( @"((""((?<token>.*?)(?<!\\)"")|(?<token>[\w]+))(\s)*)", options ); string input = @" Here is ""my string"" it has "" six matches"" "; var result = (from Match m in regex.Matches( input ) where m.Groups[ "token" ].Success select m.Groups[ "token" ].Value).ToList(); for ( int i = 0; i < result.Count(); i++ ) { Debug.WriteLine( string.Format( "Token[{0}]: '{1}'", i, result[ i ] ) ); } 

debugging输出:

 Token[0]: 'Here' Token[1]: 'is' Token[2]: 'my string' Token[3]: 'it' Token[4]: 'has' Token[5]: ' six matches' 

我正在使用Bartek Szabat的答案,但是我需要在我的标记中捕获更多的“\ w”字符。 为了解决这个问题,我修改了他的正则expression式,类似于Grzenio的回答:

 Regular Expression: (?<match>[^\s"]+)|(?<match>"[^"]*") C# String: (?<match>[^\\s\"]+)|(?<match>\"[^\"]*\") 

Bartek的代码(它返回的标记去除了引号)变成:

 Regex .Matches(input, "(?<match>[^\\s\"]+)|(?<match>\"[^\"]*\")") .Cast<Match>() .Select(m => m.Groups["match"].Value) .ToList() .ForEach(s => Console.WriteLine(s)); 

最好的答案不适合我。 我试图用空格分割这种types的string,但它看起来也像点('。')分开。

 "the lib.lib" "another lib".lib 

我知道这个问题是关于正则expression式的,但是我最终写了一个非正则expression式来完成这个任务:

  /// <summary> /// Splits the string passed in by the delimiters passed in. /// Quoted sections are not split, and all tokens have whitespace /// trimmed from the start and end. public static List<string> split(string stringToSplit, params char[] delimiters) { List<string> results = new List<string>(); bool inQuote = false; StringBuilder currentToken = new StringBuilder(); for (int index = 0; index < stringToSplit.Length; ++index) { char currentCharacter = stringToSplit[index]; if (currentCharacter == '"') { // When we see a ", we need to decide whether we are // at the start or send of a quoted section... inQuote = !inQuote; } else if (delimiters.Contains(currentCharacter) && inQuote == false) { // We've come to the end of a token, so we find the token, // trim it and add it to the collection of results... string result = currentToken.ToString().Trim(); if (result != "") results.Add(result); // We start a new token... currentToken = new StringBuilder(); } else { // We've got a 'normal' character, so we add it to // the curent token... currentToken.Append(currentCharacter); } } // We've come to the end of the string, so we add the last token... string lastResult = currentToken.ToString().Trim(); if (lastResult != "") results.Add(lastResult); return results; } 

我发现在这个答案正则expression式是非常有用的。 为了使它在C#中工作,你将不得不使用MatchCollection类。

 //need to escape \s string pattern = "[^\\s\"']+|\"([^\"]*)\"|'([^']*)'"; MatchCollection parsedStrings = Regex.Matches(line, pattern); for (int i = 0; i < parsedStrings.Count; i++) { //print parsed strings Console.Write(parsedStrings[i].Value + " "); } Console.WriteLine(); 

这个正则expression式将根据上面给出的情况进行拆分,尽pipe它不会去除引号或多余的空格,所以您可能需要对string进行一些后处理。 这应该正确地保持引用string虽然。

 "[^"]+"|\s?\w+?\s 

随着一点点混乱,常规语言可以跟踪奇数的引号计数,但是如果你的数据可以包含转义引号(\“),那么你真正的麻烦,生产或理解一个正则expression式,将正确处理。

肖恩,

我相信下面的正则expression式应该这样做

 (?<=")\w[\w\s]*(?=")|\w+ 

问候,
利芬

编辑:对不起,我以前的post,这显然是可能的。

要处理所有非字母数字字符,您需要如下所示:

 MatchCollection matchCollection = Regex.Matches(input, @"(?<match>[^""\s]+)|\""(?<match>[^""]*)"""); foreach (Match match in matchCollection) { yield return match.Groups["match"].Value; } 

如果您使用.Net> 2.0,则可以使foreach变得更加智能

在Code项目上查看LSteinle的“ 支持文本限定符的分割函数 ”

这是他感兴趣的项目片段。

 using System.Text.RegularExpressions; public string[] Split(string expression, string delimiter, string qualifier, bool ignoreCase) { string _Statement = String.Format("{0}(?=(?:[^{1}]*{1}[^{1}]*{1})*(?![^{1}]*{1}))", Regex.Escape(delimiter), Regex.Escape(qualifier)); RegexOptions _Options = RegexOptions.Compiled | RegexOptions.Multiline; if (ignoreCase) _Options = _Options | RegexOptions.IgnoreCase; Regex _Expression = New Regex(_Statement, _Options); return _Expression.Split(expression); } 

只要注意在循环中调用它,因为每次调用它时都会创build并编译Regex语句。 所以如果你需要调用更多,那么我会考虑创build一个正则expression式caching。

如果您想以免费的开放源代码javascript对象的forms来看看这个问题的一般解决scheme,您可以访问http://splitterjsobj.sourceforge.net/进行实时演示(和下载); 。 该对象具有以下function:

  • 成对的用户定义的引号字符可以用来转义分隔符(防止引号内分割)。 引号可以用用户定义的转义字符和/或“双引号转义”来转义。 逃逸字符可以逃脱(本身)。 在5个输出数组之一(对象的属性)中,输出是未转义的。 (例如,如果转义char = /,“a ///”b“被转义为a /”b“
  • 分割一系列分隔符; 在一次调用中parsing文件。 (输出数组将被嵌套。)
  • 所有由javascript识别的转义序列都可以在拆分过程和/或预处理过程中进行评估。
  • callbackfunction
  • 跨浏览器一致性

该对象也可用作jQuery插件,但作为本站的新用户,我只能在此消息中包含一个链接。