我正试图为内部标记语言开发一个代码验证系统,但由于我对正则表达式缺乏经验,我遇到了一些麻烦。该语言中的标签遵循以下格式:
{tag:number:短语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]
谢谢你的帮助。
如果有人想深入了解数据验证系统通常是如何工作的,我将不胜感激。
这看起来像是一个合适的语法和使用解析工具的地方,如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}]?
所做的任何操作 - 看起来你走在了正确的轨道上,但你可能把一些事情过于复杂了,很可能是你的空白表达式搞砸了你的正则表达式。我鼓励使用我在上面链接的工具regexpal.com,逐个测试您的regex,看看哪些地方没有按预期工作
更新2
非常怀疑您是否能够添加标志,但x
标志会大大缩短此正则表达式:
{(w+):([3-8].[05])(|[^|*n]*)*(|[^|*n]**)(|[^|*n]*)*}