首页 > 解决方案 > 这个黄瓜正则表达式有什么问题?

问题描述

我试图定义这个自定义参数类型:

ParameterType("complex", """(?x)
    | complex\( \s*
    |   (?:
    |     ($realRegex)
    |     (?:
    |       \s* ([+-]) \s* ($realRegex) \s* i
    |     )?
    |   |
    |     ($realRegex) \s* i
    |   )
    | \s* \)
    |""".trimMargin()) {
        realPartString: String?, joiner: String?, imaginaryPartString1: String?, imaginaryPartString2: String? ->

        // handling logic omitted as it doesn't matter yet
}

Cucumber 报错:

java.util.NoSuchElementException
    at java.base/java.util.Spliterators$2Adapter.nextInt(Spliterators.java:733)
    at java.base/java.util.PrimitiveIterator$OfInt.next(PrimitiveIterator.java:128)
    at java.base/java.util.PrimitiveIterator$OfInt.next(PrimitiveIterator.java:86)
    at io.cucumber.cucumberexpressions.GroupBuilder.build(GroupBuilder.java:18)
    at io.cucumber.cucumberexpressions.GroupBuilder.build(GroupBuilder.java:21)
    at io.cucumber.cucumberexpressions.GroupBuilder.build(GroupBuilder.java:21)
    at io.cucumber.cucumberexpressions.TreeRegexp.match(TreeRegexp.java:78)
    at io.cucumber.cucumberexpressions.Argument.build(Argument.java:15)
    at io.cucumber.cucumberexpressions.CucumberExpression.match(CucumberExpression.java:144)
    at io.cucumber.core.stepexpression.StepExpression.match(StepExpression.java:22)
    at io.cucumber.core.stepexpression.ArgumentMatcher.argumentsFrom(ArgumentMatcher.java:30)

听起来好像我错过了一个闭幕小组,但我已经盯着它看了好几个小时,还看不出我做错了什么。

我想也许把它扔给 StackOverflow 会立即让人发现问题。哈哈

如果重要,定义$realRegex如下:

private const val doubleTermRegex = "\\d+(?:\\.\\d+)?"
private const val realTermRegex = "(?:-?(?:√?(?:$doubleTermRegex|π)|∞))"
const val realRegex = "(?:$realTermRegex(?:\\s*\\/\\s*$realTermRegex)?)"

该代码已经存在了更长的时间,并且经过了许多测试,所以我猜问题出在新代码中,但我猜你永远不知道。

正在使用的版本:

无论如何,这是上下文的整个文件。

package garden.ephemeral.rocket.util

import garden.ephemeral.rocket.util.RealParser.Companion.realFromString
import garden.ephemeral.rocket.util.RealParser.Companion.realRegex
import io.cucumber.java8.En

class ComplexStepDefinitions: En {
    lateinit var z1: Complex
    lateinit var z2: Complex

    init {
        ParameterType("complex", """(?x)
            | complex\( \s*
            |   (?:
            |     ($realRegex)
            |     (?:
            |       \s* ([+-]) \s* ($realRegex) \s* i
            |     )?
            |   |
            |     ($realRegex) \s* i
            |   )
            | \s* \)
            |""".trimMargin()) {
                realPartString: String?,
                joiner: String?,
                imaginaryPartString1: String?,
                imaginaryPartString2: String? ->

            if (realPartString != null) {
                if (imaginaryPartString1 != null) {
                    val imaginarySign = if (joiner == "-") -1.0 else 1.0
                    Complex(realFromString(realPartString), imaginarySign * realFromString(imaginaryPartString1))
                } else {
                    Complex(realFromString(realPartString), 0.0)
                }
            } else if (imaginaryPartString2 != null) {
                Complex(0.0, realFromString(imaginaryPartString2))
            } else {
                throw AssertionError("It shouldn't have matched the regex")
            }
        }
    }
}

标签: regexkotlincucumbercucumber-java

解决方案


您已用作(?x)标志表达式来启用模式中的空格和注释。考虑到怪物的大小,这可能是一个好主意。

当使用 Cucumber 表达式时,Cucumber 会解析你的正则表达式。并且解析器不包括对您现在所遇到的标志表达式的支持。将 Cucumber 更新到最新版本应该可以解决该问题。不客气。


推荐阅读