Regex.Split()使用(和)作为分隔符,除非用单引号括起来

本文关键字:起来 单引号 使用 Split Regex 分隔符 | 更新日期: 2023-09-27 18:02:35

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

"lambda"("VARIABLE(","VARIABLE(*"(表达式(表达式(+

并且需要将其拆分为用空格(和(和[和]分隔的标记,除非(或(立即被单引号包围。

我想创建一个正则表达式,用于C#的regex.Splitt((方法,该方法将字符串拆分为以下标记:

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

我以前使用过以下正则表达式:

(?=[''(''(''|''['']](|(?<=[''

除了当(或(被单引号包围时,在这种情况下

'('

被分离到

[',(,']

我们非常感谢您的帮助。

编辑

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

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

Regex.Split()使用(和)作为分隔符,除非用单引号括起来

一旦您知道可以通过将分隔符放置在组中来拆分来保留分隔符,那么实现此功能的正则表达式就会变得更简单。

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

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[']]:在空白处拆分,[]