Regex I';我的正则表达式匹配案例有问题,我不知道';我不希望它(数据验证)

Regex I';我的正则表达式匹配案例有问题,我不知道';我不希望它(数据验证),regex,validation,Regex,Validation,我正试图为内部标记语言开发一个代码验证系统,但由于我对正则表达式缺乏经验,所以遇到了一些小问题。该语言中的标记采用以下格式: {标记:编号:短语1 |短语2…|短语n} 其中,number是范围(3.0、3.5、4.0…8.5)内的数字,且其中一个短语的末尾必须有一个星号,并且必须至少有两个短语。请注意,标记不区分大小写,空格不重要 我使用的正则表达式是: \{ ?(mw) ?: ?[3-8]{1}(.0|.5)? ?((((\| ?(\w ?)+[\p{P}]? ?)*)+((\| ?(\w\

我正试图为内部标记语言开发一个代码验证系统,但由于我对正则表达式缺乏经验,所以遇到了一些小问题。该语言中的标记采用以下格式:

{标记:编号:短语1 |短语2…|短语n}

其中,number是范围(3.0、3.5、4.0…8.5)内的数字,且其中一个短语的末尾必须有一个星号,并且必须至少有两个短语。请注意,标记不区分大小写,空格不重要

我使用的正则表达式是:

\{ ?(mw) ?: ?[3-8]{1}(.0|.5)? ?((((\| ?(\w ?)+[\p{P}]? ?)*)+((\| ?(\w\ ?)+[\p{P}]?)* ?\* ?)+((\| ?(\w ?)+[\p{P}]? ?)*)?)|(((\| ?(\w ?)+[\p{P}]? ?)*)?((\| ?(\w ?)+[\p{P}]?)* ?\* ?)+((\| ?(\w ?)+[\p{P}]? ?)*)+))( ?\})
以下哪种情况与正确的情况相匹配:

{ mw : 3.5 | phrase 1 | phrase 2* | phrase 3}
还有以下不正确的情况:

{ mw : 3.5 | phrase 1* | phrase 2* | phrase 3} [Two asterisks]

谢谢你的帮助


如果有人想深入了解数据验证系统通常是如何工作的,我将非常感谢。

这看起来是一个合适语法的地方,可以使用解析工具(如yacc、antlr…ect)来构建代码,从而真正为您进行解析。正则表达式只能做这么多,但看起来可能有一个不精确的DSL定义

或者您需要使用多个正则表达式来验证无法使用单个表达式找到的特殊情况。

此处:

\{\s*(\w+)\s*:\s*([3-8]\.[05])\s*(\|[^|*\n]*)*(\|[^|*\n]*\*\s*)(\|[^|*\n]*)*\}
下面是使用以下输入进行测试的示例:

{ mw : 3.5  | hello,  world  | says  | i  }
{ mw : 3.5  | hello,* world  | says  | i  }
{ mw : 3.5  | hello,  world* | says  | i  }
{ mw : 3.5  | hello,  world  | says* | i  }
{ mw : 3.5  | hello,  world  | says  | i* }
{ mw : 3.5    }
{ mw : 3.5  | }
{ mw : 3.5* | }
{ mw : 3.5  | hello, world  }
{ mw : 3.5  | hello, world* }
更新

一些注释

  • 在原始正则表达式中,
    表示“0或1个空格字符”。您可能指的是
    \s*
    ,意思是“0个或更多空白字符”
  • 在原始正则表达式中,请注意
    (.0 |.5)
    实际上匹配
    A0
    B5
  • 您可能需要修改我的正则表达式,以重新定义您使用
    [\p{p}]?
    所做的任何操作
  • 看起来你的思路是对的,但是你可能把一些事情复杂化了,很可能是你的空白表达式的一些古怪的东西把你的正则表达式搞乱了。我鼓励使用我上面链接的工具,逐个测试您的正则表达式,看看哪里没有按预期工作
  • 更新2

    非常怀疑您是否能够添加标志,但是
    x
    标志将大大缩短此正则表达式:

    \{(\w+):([3-8]\.[05])(\|[^|*\n]*)*(\|[^|*\n]*\*)(\|[^|*\n]*)*\}
    

    如果您考虑三种不同的情况(如@archeong87的回答):1)短语,后跟带星号的短语,2)带星号的短语,后跟不带星号的短语,以及3)带星号的短语,由不带星号的短语包围。@fork0-这也行,但实际上我所做的是:0个或更多没有星号的短语,1个带星号的短语,以及0个或更多没有星号的短语。实际上是一样的,但你的措辞建议更多地使用交替,
    |
    。这是一个要求,恐怕…@fork0-Hm,我不这么认为;下面的解决方案不使用替换。我相信OP要求使用“\s*”(空格不重要)非常感谢。这简化了很多事情,但现在我有两个问题。正则表达式现在只匹配1个单词长度的短语(这没有意义,因为您使用的是与我相同的\w+标记)。“|hello | world*|说…”效果很好,但“|hello world*|说…”效果不好。还有(?:确切的意思是什么?但实际上这是一个非常好的答案,正则表达式比我的要简洁得多。我删除了
    ?:
    ,意识到你可能没有使用捕获。它只是说“不要捕获这个组。”出于某种原因,我没有意识到你要用多个词。我会更新一下答案。更新了正则表达式、演示等等。这需要一些解释。首先,忽略
    \n
    s——你甚至可以删除它们——它们只是演示所需的。其次,忽略
    \n
    [^ |*]*
    意味着“任何非管道非星号字符字符串。"这允许在短语中使用标点符号和unicode字符。
    \w+
    不起作用,因为
    \w
    不包含空格,这当然是多词短语所必需的。这不允许在短语中带有星号的短语,对吗?像这样:
    短语*1
    *好的*短语
    ?如果是的话,我同意谈到HTML或其他涉及递归嵌套组的内容,但是这个问题没有递归,并且很容易由正则表达式处理。只有当
    不是嵌套括号中的短语分隔符时,例如
    ()
    []
    {}
    ,才会出现问题。
    \{(\w+):([3-8]\.[05])(\|[^|*\n]*)*(\|[^|*\n]*\*)(\|[^|*\n]*)*\}