Groovy 解析 GString 样式变量时的正则表达式 PatternSyntaxException
Groovy regex PatternSyntaxException when parsing GString-style variables
Groovy 这里。我得到了一个 String
和 GString-style 变量,比如:
String target = 'How now brown ${animal}. The ${role} has oddly-shaped ${bodyPart}.'
请记住,这 不是 打算用作实际的 GString!!!也就是说,我不会有 3 个字符串变量(分别为 animal
、role
和 bodyPart
)Groovy 将在 运行 时解析. 相反,我希望对这些 "target" 字符串做 2 件不同的事情:
- 我希望能够在目标字符串中找到这些变量 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
${*}
^
知道我哪里出错了吗?
问题是你没有正确转义模式,findAll
只会收集所有匹配项,而你需要 捕获 [=] 中的子模式12=].
使用
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]
在 /$\{([^{}]*)\}/
斜杠字符串中,您可以使用单个反斜杠来转义特殊的正则表达式元字符,整个正则表达式模式看起来更清晰。
$
- 将匹配文字 $
\{
- 将匹配文字 {
([^{}]*)
- 第 1 组 捕获 除 {
和 }
之外的任何字符,0 次或更多次
\}
- 文字 }
.
Groovy 这里。我得到了一个 String
和 GString-style 变量,比如:
String target = 'How now brown ${animal}. The ${role} has oddly-shaped ${bodyPart}.'
请记住,这 不是 打算用作实际的 GString!!!也就是说,我不会有 3 个字符串变量(分别为 animal
、role
和 bodyPart
)Groovy 将在 运行 时解析. 相反,我希望对这些 "target" 字符串做 2 件不同的事情:
- 我希望能够在目标字符串中找到这些变量 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
${*}
^
知道我哪里出错了吗?
问题是你没有正确转义模式,findAll
只会收集所有匹配项,而你需要 捕获 [=] 中的子模式12=].
使用
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]
在 /$\{([^{}]*)\}/
斜杠字符串中,您可以使用单个反斜杠来转义特殊的正则表达式元字符,整个正则表达式模式看起来更清晰。
$
- 将匹配文字$
\{
- 将匹配文字{
([^{}]*)
- 第 1 组 捕获 除{
和}
之外的任何字符,0 次或更多次\}
- 文字}
.