寻求PCRE正则验证Gherkin语句结构正确性的技术解决方案
识别格式错误的多行Gherkin语句的PCRE正则方案
需求回顾
需要用PCRE正则识别格式错误的多行Gherkin代码,不能用代码逻辑辅助。正确的Gherkin结构顺序严格遵循:Feature > 可选Rule > 可选Background > 可选Scenarios/Examples容器(内部至少包含一个Scenario/Example) > 每个Scenario/Example必须包含Given,且Given后至少有一个When/Then/But/And/*步骤
备注:Scenarios/Examples、Scenario/Example、And/*互为别名;必须存在至少一个Scenario/Example。
现有问题分析
之前尝试通过“匹配正确格式再取反”的思路,但写出的正则存在逻辑漏洞:
- 允许Rule与Background之间出现Scenario/Example,违反结构顺序
- 未处理Scenarios/Examples容器的情况
- 未严格校验每个Scenario/Example内部的步骤结构
之前尝试的正则:
非捕获组版本:
(Feature:[\s\S]+?)(?:Rule:[\s\S]+?)?(?:Background:[\s\S]+?)?(Scenario:[\s\S]+?)(Given:[\s\S]+?)(When|Then|And|\*)[\s\S]*?((?=(Scenario|Feature|$)))
负前瞻版本:
(Feature:[\s\S]+)(?=(Rule:[\s\S]+)?)(?=(Background:[\s\S]+)?)(?=(Scenario:[\s\S]+)*)
有效解决方案
第一步:编写匹配正确格式的PCRE正则
这个正则严格遵循结构顺序,确保每个块只能接允许的下一个元素,同时校验场景内部的步骤结构:
(?m)^Feature:[\s\S]+?(?=^\s*(?:Rule|Background|Scenario|Scenarios|Example|Examples|$)) (?:^\s*Rule:[\s\S]+?(?=^\s*(?:Background|Scenario|Scenarios|Example|Examples|$)))? (?:^\s*Background:[\s\S]+?(?=^\s*(?:Scenario|Scenarios|Example|Examples|$)))? (?:^\s*(?:Scenarios|Examples):[\s\S]+?)? (?:^\s*(?:Scenario|Example):[\s\S]+?^\s*Given:?[\s\S]+?(?:^\s*(?:When|Then|But|And|\*):?[\s\S]+?)+)+ (?=^\s*(?:Feature|$))
正则说明:
(?m):开启多行模式,让^匹配每行开头- 每个块通过正前瞻
(?=...)限制后续只能出现允许的关键字或结束,避免顺序错误 - 场景部分强制要求至少一个Scenario/Example,且每个场景必须包含Given及后续步骤
- 支持Scenarios/Examples容器的可选包裹
第二步:识别错误格式
有两种方式实现错误识别:
- 反向匹配:在支持PCRE的工具(如
grep -P、regex101)中,使用反向匹配功能(比如grep -Pv),用上面的正确正则匹配,未被匹配的内容就是格式错误的Gherkin。 - 直接匹配错误结构:编写正则直接命中违反规则的情况,比如:
(?m)(?:^\s*(?:Scenario|Example|Scenarios|Examples):(?=^\s*(?:Rule|Background:))|^\s*Given:?(?=^(?!\s*(?:Scenario|Example):))|^\s*(?:When|Then|But|And|\*):?(?=^(?!\s*(?:Given|When|Then|But|And|\*):))|^Feature:[\s\S]+?(?!^\s*(?:Rule|Background|Scenario|Scenarios|Example|Examples|$))|^\s*Rule:[\s\S]+?(?!^\s*(?:Background|Scenario|Scenarios|Example|Examples|$))|^\s*Background:[\s\S]+?(?!^\s*(?:Scenario|Scenarios|Example|Examples|$))|(?!^\s*(?:Scenario|Example):[\s\S]+?^\s*Given:)^\s*(?:Scenario|Example):)
这个正则会匹配以下错误情况:
- 场景关键字(Scenario/Example等)出现在Rule或Background之前
- Given步骤不在Scenario/Example块内
- When/Then等步骤没有前置的Given或其他合法步骤
- Feature/Rule/Background后面出现不允许的内容
- Scenario/Example块中没有Given步骤
内容的提问来源于stack exchange,提问作者Shawn
相关产品推荐
相关产品推荐

