Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何生成递归正则表达式_C#_.net_Regex - Fatal编程技术网

C# 如何生成递归正则表达式

C# 如何生成递归正则表达式,c#,.net,regex,C#,.net,Regex,我想创建一个能够为我匹配一些逻辑公式的正则表达式,以验证输入 基本上,我会有一个数字(0-100),一个关键字(和/或)和括号 因此,我应该能够匹配此类用例: 1 AND 2 (1 AND 2) OR 3 1 AND (2 OR 3) (1 AND 2) OR (3 AND 4) 1 AND (2 OR (3 AND (4 OR 5))) 我不需要验证它是最简单的表单(比如阻止用户编写(1和(2和3)) 到目前为止,我已经创建了以下内容: \(?(\d+)\s+(AND|OR)\s+\d+\)

我想创建一个能够为我匹配一些逻辑公式的正则表达式,以验证输入

基本上,我会有一个数字(0-100),一个关键字(和/或)和括号

因此,我应该能够匹配此类用例:

1 AND 2
(1 AND 2) OR 3
1 AND (2 OR 3)
(1 AND 2) OR (3 AND 4)
1 AND (2 OR (3 AND (4 OR 5)))
我不需要验证它是最简单的表单(比如阻止用户编写
(1和(2和3))

到目前为止,我已经创建了以下内容:

\(?(\d+)\s+(AND|OR)\s+\d+\)?
但我有几件事要做:

  • 是否有某种方法可以使用正则表达式(在C#)执行递归操作?因为我不应该限制括号级别。目标是使
    \d+
    或相同的整个表达式
  • 我不知道如何强制执行,如果添加了一个开括号,我还应该有一个右括号

  • 正则表达式:语法规则,它解析规则的和通常的非递归结构,一般不解析递归结构,如:JSON、HTML、数学表达式、布尔表达式、C++、C语言、java等。它不适合其他语法,正则表达式在有限状态自动机上工作,而任务涉及上下文。(这就是为什么需要堆栈),因此您应该使用下一级语法层次结构:

    您通常希望通过使用带有堆栈的硬编码自动机(如注释中建议的)或使用框架根据LR/LL语法解析输入来完成的工作:ANTLR、Gold、pegasus等

    例如,ANTLR有很多语法:github.com/ANTLR/grammars-v4。 如果深入研究一下语法,你会发现你的问题在多个语法中都有答案:


    < /P> < P>正则表达式:java语法规则,它解析规则的,通常是非递归的结构,一般不解析递归结构,如:JSON、HTML、数学表达式、布尔表达式、C++、C语言、Java等。它不适合其他语法,正则表达式在有限状态自动机上工作,而任务涉及CON。文本(这就是为什么需要堆栈),因此您应该使用下一级语法层次结构:

    您通常希望通过使用带有堆栈的硬编码自动机(如注释中建议的)或使用框架根据LR/LL语法解析输入来完成的工作:ANTLR、Gold、pegasus等

    例如,ANTLR有很多语法:github.com/ANTLR/grammars-v4。 如果深入研究一下语法,你会发现你的问题在多个语法中都有答案:


    你在工作中使用了错误的工具。.NET正则表达式不提供递归,特别是我不确定它是否能识别所有的CFG,这本身就是一个有趣的问题。因此,如果你的问题是,嗯,学术兴趣,那么你可以提前阅读。如果你真的想在某些产品中使用它那么,请不要使用密码

    也就是说,为了匹配括号,您可以使用。根据匹配尖括号的文档改编示例,您将得到以下结果:

    ^[^\(\)]*(((“打开”\()[^\(\)]*)+(((“关闭-打开”\)[^\(\)]*)+)*(((打开)(?!)$
    
    括号内的内容由上面的表达式
    [^\(\)]*
    定义。我没有成功地尝试将数字和/或规则纳入其中,同时又没有失去理智,并创建了一个长度远远超过联邦法规的正则表达式

    但是,我们可以结合使用多个正则表达式来验证您的输入。首先,请忽略括号,并确保表达式的一般形式为
    number(和/或number)*

    ^[\(\)]*([0-9][1-9][0-9][100](\s(和/或)\s[\(\)]*([0-9][1-9][0-9][100][\(\)]*)*$
    
    上述模式已排除空括号和带有单个数字的括号。仍需排除使用多个和/或在单个括号内的字符串,如
    1或2和3
    1或(2和3和4)
    1和2或(1和2)

    (\d)+\s*(和|或)\s*(\d)+\s*(和|或)
    
    因此,要验证您的输入,您需要运行所有三个正则表达式,并断言前两个匹配,而最后一个不匹配

    顺便说一句,您可能可以将这三个正则表达式用作分支指令,并组合成一个单独的正则表达式,该正则表达式声明与前两个正则表达式匹配,而与最后一个正则表达式不匹配。这是留给读者的一个练习,因为这同样是不可读的

    您可以找到一个工作正常的dotnetfiddle演示。以下代码供参考:

    使用系统;
    使用System.Text.RegularExpressions;
    var-correctoreparanthesis=newregex(@“^[^\(\)]*(((?'Open'\()[^\(\)]*)+(((?'Close-Open'\))[^\(\)]*)+(?(Open)(?!)$);
    var correctStructure=new Regex(@“^[\(\)]*([0-9]|[1-9][0-9]|[100”)(\s(和|或)\s[\(\)]*([0-9]|[1-9][0-9]| 100][\(\)*)”;
    var ambiguousClauses=新正则表达式(@“(\d)+\s*(和|或)\s*(\d)+\s*(和|或)”;
    bool验证(字符串输入)=>
    !string.IsNullOrWhiteSpace(输入)&&
    修正了IsMatch(输入)和
    更正结构。IsMatch(输入)和
    !ambiguousClauses.IsMatch(输入);
    var validInputs=新[]
    {
    “1和2”,
    “(1和2)或3”,
    “1及(2或3)”,
    “(1及2)或(3及4)”,
    “1及(2或(3及(4或5))”,
    “(((1及2)或(3)及(4)或(5)”,
    "1"
    };
    var invalidinput=new[]
    {
    “(1和2)或3”,
    “((1和2)或3”,
    "(1)",
    "()",
    "101",
    “1和2”,
    “及1及”,
    “和”,
    “1和2”,
    “1或2和3”,
    “1或(2及3及4)”,
    “1及2或(1及2)”
    };
    foreach(var validInput在validInputs中)
    {
    var isValid=验证(validInput);
    如果(!isValid)
    {
    抛出新异常($“有效输入{validInput}未验证。”);
    }
    }
    foreach(var INVALIDIPUT in INVALIDIPUTS)
    {
    var isValid=验证(invalidInput);
    如果(有效)
    {
    抛出新异常($“无效输入{invalidInput}已验证”);
    }
    }
    控制台。WriteLine(“所有案例均通过”);