1

这里很时髦。我得到了一个String带有 GString风格的变量,比如:

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

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

  • 我希望能够"${*}"在目标字符串中找到这些变量 refs ( ) 的所有实例,并将其替换为?; 和
  • 我还需要找到这些变量 refs 的所有实例并获取一个列表(允许欺骗)及其名称(在上面的示例中,将是[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
${*}
^

有什么想法我会出错吗?

4

1 回答 1

1

问题是您没有正确转义模式,findAll只会收集所有匹配项,而您需要{}.

采用

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]

查看这个 Groovy 演示

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

  • \$- 将匹配文字$
  • \{- 将匹配文字{
  • ([^{}]*)- 组 1捕获{除and以外的任何字符},0 次或更多次
  • \}- 文字}
于 2016-07-28T09:41:15.263 回答