如何在Behat中使用正则表达式作为通配符查找字符串?
在Behat中使用正则表达式匹配文本
你的思路方向是对的,但问题出在CSS的:contains()选择器根本不支持正则表达式——它只能做字面文本匹配,所以你把正则片段直接替换进选择器字符串里,肯定找不到对应内容,返回null是意料之中的。
要实现正则匹配文本的需求,我们需要换个思路:先获取目标元素(或整个页面)的文本内容,再用PHP的正则函数去匹配,而不是依赖CSS选择器。
修改后的实现代码
这里是调整后的Behat步骤定义,解决了你的问题:
/** * @Then I should see the text :textTemplate with wildcard matching :regexPattern */ public function iShouldSeeTheTextWithWildcardMatching($textTemplate, $regexPattern) { // 移除用户传入正则的分隔符(比如前后的/) $cleanRegex = trim($regexPattern, '/'); // 转义模板中的正则特殊字符,确保固定文本部分被字面匹配 $escapedTemplate = preg_quote($textTemplate, '/'); // 将模板中的WILDCARD替换为用户提供的正则片段,构建完整正则 $fullRegex = str_replace('WILDCARD', $cleanRegex, $escapedTemplate); // 可选:添加^和$锚点,确保匹配整个元素文本(如果不需要全匹配可以去掉) $fullRegex = "/^$fullRegex$/"; // 定位到目标提示元素(你原来的success alert) $alertElement = $this->getSession()->getPage()->find('css', 'div.alert-success'); // 先检查元素是否存在 if (!$alertElement) { throw new \Exception('Success alert element not found on the page.'); } // 获取元素的纯文本内容 $elementText = $alertElement->getText(); // 执行正则匹配 if (!preg_match($fullRegex, $elementText)) { throw new \Exception(sprintf( 'Expected text matching pattern "%s", but found: "%s"', $fullRegex, $elementText )); } }
关键要点解释
放弃CSS :contains():
这个选择器只能匹配字面字符串,不支持任何正则语法,所以我们直接跳过它,改用PHP的preg_match做匹配。处理正则分隔符:
很多人习惯写带/包裹的正则(比如/[A-Z]°[0-9]+/),代码里用trim($regexPattern, '/')去掉这些分隔符,避免干扰正则解析。转义模板文本:
用preg_quote转义模板里的特殊字符(比如单引号、逗号),确保这些固定文本部分被当作字面量匹配,不会被正则引擎误解析为特殊语法。灵活的匹配范围:
- 如果需要匹配整个元素的文本,保留
^和$锚点; - 如果只需要元素文本中包含匹配片段,去掉锚点即可(改成
"/$fullRegex/"); - 如果要匹配整个页面的任意文本,把
$alertElement->getText()换成$this->getSession()->getPage()->getText()。
- 如果需要匹配整个元素的文本,保留
使用示例
针对你提到的场景,你的Gherkin步骤可以这样写:
And I should see the text "The content 'WILDCARD', of type 'ISAI', has been created" with wildcard matching "/[A-Z]°[0-9]+/"
这个步骤会匹配类似The content 'N° 1', of type 'ISAI', has been created或The content 'X°123', of type 'ISAI', has been created的文本。
内容的提问来源于stack exchange,提问作者Jaeger
相关产品推荐
相关产品推荐

