Groovy字符串替换所有不能按预期工作

时间:2016-08-04 13:11:20

标签: regex string groovy

我有一串有效的XML(包含XML标记,属性,注释,空格等),其中包含表单的特殊标记:

  

%(*)

例如,%(testLibDir)%(ivySettingsFile)

我正在尝试将%(*)的所有实例替换为${*}。例如,如果我的XML字符串中存在%(testLibDir)(无论出现多少次),那么我希望将其转换为${testLibDir}等。

迄今为止我最好的尝试:

static void main(String[] args) {
    // In reality the XML string will be generated dynamically at runtime.
    String xml = """
  <project name="some-name" default="dist" basedir="." xmlns:ivy="antlib:org.apache.ivy.ant">

  <!-- specify properties in build.properties -->
  <property file="build.properties" />

  <taskdef name="ivy-configure" classname="org.apache.ivy.ant.IvyConfigure" />
  <taskdef name="ivy-resolve" classname="org.apache.ivy.ant.IvyResolve" />
  <taskdef name="ivy-retrieve" classname="org.apache.ivy.ant.IvyRetrieve" />
  <taskdef name="ivy-cleancache" classname="org.apache.ivy.ant.IvyCleanCache" />

  <!-- Identify the Ivy settings file to use -->
  <ivy:settings file="%(ivySettingsFile)" />

  <target name="test-resolve">
    <delete>
      <fileset dir="%(testLibDir)" includes="*.jar" />
    </delete>
    <ivy:resolve file="test-ivy.xml" conf="compile" />
    <ivy:retrieve pattern="%(testLibDir)/[artifact]-[type]-[revision].[ext]" conf="compile" />
  </target>
  """
    println "Final XML is:\n${xml.replaceAll('%(', '\${').replaceAll(')', '}')}"
}

上面的println会产生以下堆栈跟踪:

log4j:ERROR Could not find value for key log4j.appender.stdout.layout
log4j:WARN No such property [file] in org.apache.log4j.ConsoleAppender.
Exception in thread "main" java.util.regex.PatternSyntaxException: Unclosed group near index 2
%(
^
    at java.util.regex.Pattern.error(Pattern.java:1955)
    at java.util.regex.Pattern.accept(Pattern.java:1813)
    at java.util.regex.Pattern.group0(Pattern.java:2908)
    (rest of stack trace omitted for brevity)

我出错的任何想法以及我可以做些什么来修复我的字符串替换?

1 个答案:

答案 0 :(得分:2)

您需要使用正则表达式:

/%\(([^()]*)\)/

匹配

  • % - 百分比唱歌
  • \( - 文字(
  • ([^()]*) - 第1组捕获除()以外的0 +字符
  • \) - 文字)

请注意,模式本身最好使用斜线字符串定义,替换模式中的文字$应使用文字\进行转义,以视为文字美元符号。 $1是对第1组捕获的值的反向引用。

Groovy demo

println xml.replaceAll(/%\(([^()]*)\)/, '\\${$1}')