C# 正则表达式根据组拆分包含括号的单词

C# 正则表达式根据组拆分包含括号的单词,c#,regex,C#,Regex,我有以下术语,这些术语在一组中考虑。 创建设置和删除 对于以下输入 Create(Apple | Banana(Tree) | Mango (Tree) ) | Delete(Guava)|Set(Orange(Tree)) 预期的分割应如下所示 Create(Apple | Banana(Tree) | Mango (Tree) ) Delete(Guava) Set(Orange(Tree)) 我可以想出下面的正则表达式,它没有给出正确的分割 (Create|Set|Delete)\(.

我有以下术语,这些术语在一组中考虑。
创建
设置
删除

对于以下输入

Create(Apple | Banana(Tree) | Mango (Tree) ) | Delete(Guava)|Set(Orange(Tree))
预期的分割应如下所示

Create(Apple | Banana(Tree) | Mango (Tree) )
Delete(Guava)
Set(Orange(Tree))
我可以想出下面的正则表达式,它没有给出正确的分割

(Create|Set|Delete)\(.*\)\s*\|
如果您使用:

\s*\|\s*(?=\b(?:Create|Set|Delete)\b)
在线查看


  • \s*\\124;\ s*
    -由零个或多个空格包围的文字管道符号(贪婪)
  • (?=
    -正向前瞻:
    • \b
      -单词边界
    • (?:
      -打开非捕获组:
      • Create | Set | Delete
        -逐字匹配这些备选方案中的任何一个
      • -关闭非捕获组
    • \b
      -单词边界
    • -关闭正向前瞻
注意:只需根据您自己的尝试添加其他“关联”和“解除关联”作为备选方案即可


在c#代码中:


请再试一次。

您可以使用平衡结构:

\b(?:Create | Set | Delete)\((?>[^()]+|(?)\(|(?)\)*((c)(?!)\)

详细信息

  • \b
    -单词边界
  • (?:创建|设置|删除)
    -非捕获组中列出的备选方案之一
  • \(
    -a
    字符
  • (?>[^()]+[^())\(?)\(?)\)*
    -除
    (请参见
    [^()]+
    )或
    字符(将空值推到组“c”堆栈上)或
    字符(从组“c”堆栈中弹出一个值)以外的任何一个或多个字符的零次出现,然后
  • (?(c)(?!)
    -如果组“c”堆栈不为空,则条件匹配失败
  • \)
    -a
    字符
见:

var reg=@“\b(?:创建集删除)\((?>[^()])+(?)\(?)\((?)\)*(?(c)(?!)\)”;
var text=“创建(苹果|香蕉(树)|芒果(树))|删除(番石榴)|设置(橙色(树))”;
var result=Regex.Matches(text,reg).Cast().Select(x=>x.Value).ToList();
foreach(结果中的var s)
控制台。写入线(s);
输出:

Create(苹果|香蕉(树)|芒果(树))
删除(番石榴)
套装(橙色(树))

使用Regex.Split(inputText,expression)后,输出数组包含2个空元素。在共享的链接中,拆分列表没有expected@baskar_p为什么对要提取的正则表达式使用
Regex.Split
?使用
Regex.Matches(text,@“\b(?:Create | Set | Delete)\(?>[^()]+|(?)\(|)(?)\)*(?(c)(?!)\))”.Cast()。选择(x=>x.Value)
谢谢。我接受了@JvdV的答案,因为它在我看来更优雅。是否有您的正则表达式能够更好地处理输入的场景?@baskar\p您无法在优雅程度上比较我们的解决方案,它们匹配的文本非常不同,而我的答案则严格地提取了“一个单词+
(…)
子字符串”的模式,另一个(注意第一个
\b
单词边界是多余的,
\s*\\s*(?=(?:Create | Set | Delete)\b)
)只与一个
字符匹配,该字符包含可选的空格,该空格直接跟在字符串中任意位置的三个单词中的一个(因此,如果该字符出现在嵌套的
(…)中
它也会被拆分。@baskar\u p它在任何地方都能工作。在使用Regex.split(inputText,expression)之后,输出数组包含1个元素,即inputText本身。@baskar\u p,我包含了一些我发现的示例代码来显示它的工作原理。
using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"\s*\|\s*(?=\b(?:Create|Set|Delete)\b)";
      string input = "Create(Apple | Banana(Tree) | Mango (Tree) ) | Delete(Guava)|Set(Orange(Tree))";
      string[] result = Regex.Split(input, pattern, 
                                    RegexOptions.IgnoreCase,
                                    TimeSpan.FromMilliseconds(500));
      for (int ctr = 0; ctr < result.Length; ctr++) {
         Console.Write("'{0}'", result[ctr]);
         if (ctr < result.Length - 1) 
            Console.Write(", ");
      }
      Console.WriteLine();
   }
}
'Create(Apple | Banana(Tree) | Mango (Tree) )', 'Delete(Guava)', 'Set(Orange(Tree))'