我正在尝试为内部标记语言开发代码验证系统,但由于我对正则表达式缺乏经验,我遇到了一些麻烦。语言中的标签遵循以下格式:
{tag:number:phrase 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]
和
{ mw : 3.5* | phrase 1 | phrase 2* | phrase 3} [An asterisk with the number value]
感谢您的帮助。
如果有人想提供有关数据验证系统通常如何工作的任何见解,我将非常感谢您的见解。
答案 0 :(得分:1)
这看起来像是一个正确语法的地方,并使用解析工具,如yacc,antlr等,以构建实际将为您解析的代码。正则表达式只能做很多,但看起来你的DSL可能有一个不精确的定义。
那或者您将需要使用多个正则表达式来验证使用单个表达式无法找到的特殊情况。
答案 1 :(得分:0)
下面:
\{\s*(\w+)\s*:\s*([3-8]\.[05])\s*(\|[^|*\n]*)*(\|[^|*\n]*\*\s*)(\|[^|*\n]*)*\}
这是a demo,使用以下输入进行测试:
{ 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]*)*\}