解析GString样式的变量时,Groovy正则表达式PatternSyntaxException

时间:2016-07-28 09:26:40

标签: regex groovy gstring

Groovy在这里。我正在给它一个String的GString- 样式变量,如:

String target = 'How now brown ${animal}. The ${role} has oddly-shaped ${bodyPart}.'

请注意,旨在用作实际的GString!也就是说,我不会有3个字符串变量(分别为animalrolebodyPart)Groovy将在运行时解析。 相反,我希望对这些“目标”字符串做两件不同的事情:

  • 我希望能够在目标字符串中找到这些变量refs("${*}")的所有实例,并将其替换为?;和
  • 我还需要查找这些变量的所有实例refs并获取一个列表(允许使用dupes)及其名称(在上面的示例中,将为[animal,role,bodyPart]

迄今为止我最好的尝试:

class TargetStringUtils {
    private static final String VARIABLE_PATTERN = "\${*}"

    // Example input: 'How now brown ${animal}. The ${role} has oddly-shaped ${bodyPart}.'
    // Example desired output: 'How now brown ?. The ? has oddly-shaped ?.'
    static String replaceVarsWithQuestionMarks(String target) {
        target.replaceAll(VARIABLE_PATTERN, '?')
    }

    // Example input: 'How now brown ${animal}. The ${role} has oddly-shaped ${bodyPart}.'
    // Example desired output: [animal,role,bodyPart]    } list of strings  
    static List<String> collectVariableRefs(String target) {
        target.findAll(VARIABLE_PATTERN)
    }
}

...在我运行任何一种方法时随时生成PatternSytaxException

Exception in thread "main" java.util.regex.PatternSyntaxException: Illegal repetition near index 0
${*}
^

我出错的任何想法?

1 个答案:

答案 0 :(得分:1)

问题是您没有正确转义模式,而findAll只会收集所有匹配项,而您需要捕获 {}内的子模式。< / p>

使用

def target = 'How now brown ${animal}. The ${role} has oddly-shaped ${bodyPart}.'
println target.replaceAll(/\$\{([^{}]*)\}/, '?') // => How now brown ?. The ? has oddly-shaped ?.

def lst = new ArrayList<>();
def m = target =~ /\$\{([^{}]*)\}/
(0..<m.count).each { lst.add(m[it][1]) }
println lst   // => [animal, role, bodyPart]

请参阅this Groovy demo

/\$\{([^{}]*)\}/斜杠字符串中,您可以使用单个反斜杠来转义特殊的正则表达式元字符,整个正则表达式模式看起来更清晰。

  • \$ - 将匹配文字$
  • \{ - 将匹配文字{
  • ([^{}]*) - 第1组捕获{}以外的任何字符,0次或更多次
  • \} - 文字}