【问题标题】:Tokenize a string using multiple conditions使用多个条件标记字符串
【发布时间】:2021-08-22 00:32:18
【问题描述】:

对于下面的字符串:

var str = "value0 'value 1/5' 'x ' value2";

有没有一种方法可以解析该字符串以便得到

arr[0] = "value0";
arr[1] = "value 1/5";
arr[2] = "x ";
arr[3] = "value2";

可能带有单引号的值的顺序是任意的。大小写无关紧要。

我可以使用正则表达式获取单引号之间的所有值

"'(.*?)'"

但我需要这些值相对于其他非单引号值的顺序。

【问题讨论】:

    标签: c# regex


    【解决方案1】:

    使用

    '(?<val>.*?)'|(?<val>\S+)
    

    regex proof

    解释

    --------------------------------------------------------------------------------
      '                        '\''
    --------------------------------------------------------------------------------
      (                        group and capture to \1:
    --------------------------------------------------------------------------------
        .*?                      any character except \n (0 or more times
                                 (matching the least amount possible))
    --------------------------------------------------------------------------------
      )                        end of \1
    --------------------------------------------------------------------------------
      '                        '\''
    --------------------------------------------------------------------------------
     |                        OR
    --------------------------------------------------------------------------------
      (                        group and capture to \2:
    --------------------------------------------------------------------------------
        \S+                      non-whitespace (all but \n, \r, \t, \f,
                                 and " ") (1 or more times (matching the
                                 most amount possible))
    --------------------------------------------------------------------------------
      )                        end of \2
    

    C# code

    using System;
    using System.Text.RegularExpressions;
    
    public class Example
    {
        public static void Main()
        {
            string pattern = @"'(?<val>.*?)'|(?<val>\S+)";
            string input = @"value0 'value 1/5' 'x ' value2";
            
            foreach (Match m in Regex.Matches(input, pattern))
            {
                Console.WriteLine(m.Groups["val"].Value);
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      在 C# 中,您可以重复使用相同命名的捕获组,因此您可以使用替代 |,并为两个部分使用相同的组名。

      '(?<val>[^']+)'|(?<val>\S+)
      

      模式匹配:

      • ' 匹配单引号
      • (?&lt;val&gt;[^']+) 在组 val 中捕获匹配除 ' 之外的任何字符的 1 倍以上以不匹配空字符串
      • ' 匹配单引号
      • |或者
      • (?&lt;val&gt;\S+) 在组中捕获 val 匹配 1+ 次任何非空白字符

      查看.NET regex demoC# demo

      例如

      string pattern = @"'(?<val>[^']+)'|(?<val>\S+)";
      var str = "value0 'value 1/5' 'x ' value2";
      foreach (Match m in Regex.Matches(str, pattern))
      {
          Console.WriteLine(m.Groups["val"].Value);
      }
      

      输出

      value0
      value 1/5
      x 
      value2
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-06-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多