【问题标题】:Regex.Split() using ( and ) as delimiter except when surrounded by single quotesRegex.Split() 使用 ( 和 ) 作为分隔符,除非用单引号括起来
【发布时间】:2014-05-10 00:20:21
【问题描述】:

我有一个输入字符串,例如:

'lambda' '(' VARIABLE (',' VARIABLE)* ')' 表达式 (表达式)+

并且需要将其拆分为由空格分隔的标记,( and ) 和 [ and ],除非 ( or ) 立即被单引号括起来。

我想创建一个正则表达式以与 C# 的 Regex.Split() 方法一起使用,该方法会将字符串拆分为以下标记:

['lambda', '(', VARIABLE, (, ',' VARIABLE, ), *, ')', 表达式, (, 表达式, ), +]

我之前使用的是以下正则表达式:

(?=[ \(\)\|\[\]])|(?

效果很好,除了当 ( 或 ) 被单引号包围时,在这种情况下

'('

被分成

[', (, ']

非常感谢您的帮助。

编辑

好吧,我现在少了一个问题。这是我完全不使用正则表达式的最终解决方案:

    private void Scan()
    {
        List<char> accum = new List<char>();

        int index = 0;

        List<string> tokens = new List<string>();

        if (INPUT.Length == 0)
            return;

        while (true)
        {
            if ((index == INPUT.Length) || 
                (
                    (
                     (index == 0 || INPUT[index - 1].ToString() != "'") || 
                     (index == INPUT.Length - 1 || INPUT[index + 1].ToString() != "'") || 
                     (INPUT[index] == ' ')
                    ) 
                    &&
                    (
                     INPUT[index] == ' ' || 
                     INPUT[index] == '(' || 
                     INPUT[index] == ')' || 
                     INPUT[index] == '[' || 
                     INPUT[index] == ']' || 
                     INPUT[index] == '|'
                    )
                )
            )
            {
                string accumulatedToken = string.Join("", accum);
                string currentToken = index < INPUT.Length ? INPUT[index].ToString() : "";
                tokens.Add(accumulatedToken);
                tokens.Add(currentToken);

                CURRENT_TOKEN = tokens.FirstOrDefault(t => !string.IsNullOrWhiteSpace(t));

                INPUT = INPUT.Substring(CURRENT_TOKEN.Length).TrimStart();

                if (CURRENT_TOKEN != null)
                {
                    break;
                }

                index = 0;
            }
            else
            {
                accum.Add(INPUT[index]);
                index++;
            }
        }
    }

【问题讨论】:

    标签: c# regex


    【解决方案1】:

    一旦您知道可以通过将分隔符放在组中来split and retain a delimiter,实现这一点的正则表达式就会变得更简单。

    以下模式产生您提到的输出:

    var input = "'lambda' '(' VARIABLE (',' VARIABLE)* ')' EXPRESSION (EXPRESSION)+";
    var pattern = @"\s*('[()]'|[()])\s*|[\s[\]]";
    var result = Regex.Split(input, pattern);
    Console.WriteLine(result);
    

    模式说明:\s*('[()]'|[()])\s*|[\s[\]]

    • \s*('[()]'|[()])\s*:
      • \s*:修剪前导/尾随空格(放置在两端)
      • ('[()]'|[()]):这整个部分都放在一个组(...) 中,因为我们希望在 中的分隔符上进行拆分,并将它们包含在结果中。我们希望匹配单引号 '[()]' 内的括号和未包含在单引号 [()] 内的括号。
    • |:交替匹配第一组或下一部分
    • [\s[\]]:在空白处拆分,[]

    【讨论】:

      猜你喜欢
      • 2021-09-21
      • 2013-05-31
      • 1970-01-01
      • 1970-01-01
      • 2021-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-03
      相关资源
      最近更新 更多