【问题标题】:ant-contrib for loop and regex in ant scriptingant 脚本中的循环和正则表达式的 ant-contrib
【发布时间】:2013-10-01 11:23:13
【问题描述】:

我有一个使用 ant 的要求,即目标应提取以逗号分隔的两个参数,并在一个以分号分隔的类似参数对的长列表中提取。目前我正在做这样的事情:

<?xml version="1.0"?>

<project name="" basedir="." default="test" xmlns:ac="antlib:net.sf.antcontrib">
<target name="test" >
<echo message="Hey There I am using What's App" />
<ac:for list="asdfg,dasfdf;vxxexqxx,hyyypyly;dksfgsgdgf,abaifuacu" delimiter=";" param="val">
<ac:sequential>
<ac:propertyregex property="param1"
            input="@{val}"
            regexp="([^\.]*)\,.*"
            select="\1"
            casesensitive="true" />
<ac:propertyregex property="param2"
            input="@{val}"
            regexp=".*,([^\.]*)"
            select="\1"
            casesensitive="true" />
<echo message = "val = ${param1}"/>
<echo message = "value = ${param2}"/>
</ac:sequential>
</ac:for>
</target>
</project>

但我得到的输出是:

Buildfile: /tmp/Manish/build.xml

test:
 [echo] Hey There I am using What's App
 [echo] val = asdfg
 [echo] value = dasfdf
 [echo] val = asdfg
 [echo] value = dasfdf
 [echo] val = asdfg
 [echo] value = dasfdf

所以这循环了 3 次(正确),但只循环了 for 循环参数中传递的第一个值。我犯了什么明显的错误吗?

谢谢, 马尼什·乔希

【问题讨论】:

  • 您错过了关于 ant 的一个重要方面:它不是一种脚本语言。属性不是变量——它们是不可变的。您的要求与您的工具不匹配。 ant中没有参数。
  • ant中有参数。这就是 macrodef 的用途。这总是让我感到好笑,现在很少有人关注 macrodef 并尝试使用导致过于复杂和不可维护的 ant 脚本的目标来做所有事情。

标签: regex ant ant-contrib


【解决方案1】:

尝试使用 foreach 而不是 for 并将 propertyregex 放入单独的目标中。这是我的 ant 脚本中的一个示例,它基本上做同样的事情。

<target name="loadTestStatic" depends="setTargetEnv,setPassword">
    <loadfile property="controlFile" srcFile="${projectDir}/test/config/static/controlFile.txt"/>

    <foreach list="${controlFile}" delimiter="${line.separator}" param="descriptor" target="loadConfig"/>
</target>

<target name="loadConfig">
    <if>
        <matches string="${descriptor}" pattern="^camTool:"/>
        <then>
            <propertyregex property="camToolFile"
                           input="${descriptor}"
                           regexp="camTool:(.*)"
                           select="\1"
                           casesensitive="false" />
            <echo message="Got cam tool file ${camToolFile}"/>
            <camTool file="${camToolFile}"/>
        </then>
        <else>
            <!-- todo: add CM Tool, SQL as required -->
            <echo message="Unexpected config ${descriptor} ignored"/>
        </else>
    </if>
</target>

【讨论】:

    【解决方案2】:

    另一种方法是使用像groovy 这样的脚本语言。

      <groovy>
         <arg value="asdfg,dasfdf;vxxexqxx,hyyypyly;dksfgsgdgf,abaifuacu"/>
    
         args[0].tokenize(";").each {
            def m = it.tokenize(",")
    
            println "val   = ${m[0]}"
            println "value = ${m[1]}"
         }
      </groovy>
    

    【讨论】:

      【解决方案3】:

      或者使用 Ant 插件 Flaka, f.e. :

      <project xmlns:fl="antlib:it.haefelinger.flaka">
      
      <!-- with cvs property -->
      <property name="foobar" value="asdfg,dasfdf;vxxexqxx,hyyypyly;dksfgsgdgf,abaifuacu"/>
       <fl:for var="item" in="split('${foobar}', ';')">
        <fl:let>
         param1 ::= split(item, ',')[0]
         param2 ::= split(item, ',')[1]
        </fl:let>
        <echo>
         $${param1} => ${param1}
         $${param2} => ${param2}
        </echo>
       </fl:for>
      
       <!-- with list inline -->
       <fl:for var="item" in="split('asdfg,dasfdf;vxxexqxx,hyyypyly;dksfgsgdgf,abaifuacu', ';')">
        <fl:let>
         param1 ::= split(item, ',')[0]
         param2 ::= split(item, ',')[1]
        </fl:let>
        <echo>
         $${param1} => ${param1}
         $${param2} => ${param2}
        </echo>
       </fl:for>
      
      </project>
      

      注意 param1 ::= split(item, ',')[0] 中的双 '::' 意味着覆盖任何(也是用户属性,通过 -Dkey=value 作为命令行参数定义)现有属性 而 ':=' 创建一个属性,但如果属性已经存在则不会覆盖。

      【讨论】:

        【解决方案4】:
        <target name="myTarget">
                <ac:propertyregex property="param1"
                        input="${myValue}"
                        regexp="([^\.]*)\,.*"
                        select="\1"
                        casesensitive="true" />
                <ac:propertyregex property="param2"
                        input="${myValue}"
                        regexp=".*,([^\.]*)"
                        select="\1"
                        casesensitive="true" />
                <echo message = "val = ${param1}"/>
                <echo message = "value = ${param2}"/>
            </target>
        
            <ac:for list="asdfg,dasfdf;vxxexqxx,hyyypyly;dksfgsgdgf,abaifuacu" delimiter=";" param="val">
            <ac:sequential>
                <antcall target="myTarget">
                    <param name="myValue" value="@{val}" />
                </antcall>  
            </ac:sequential>
            </ac:for>
        

        【讨论】:

          【解决方案5】:

          Ant 中的属性是不可变的。您需要使用 ant-contrib 中的 variable task(尽管不鼓励)来取消设置属性:

          <ac:for list="asdfg,dasfdf;vxxexqxx,hyyypyly;dksfgsgdgf,abaifuacu" delimiter=";" param="val">
          <ac:sequential>
          <ac:propertyregex property="param1"
                      input="@{val}"
                      regexp="([^\.]*)\,.*"
                      select="\1"
                      casesensitive="true" />
          <ac:propertyregex property="param2"
                      input="@{val}"
                      regexp=".*,([^\.]*)"
                      select="\1"
                      casesensitive="true" />
          <echo message = "val = ${param1}"/>
          <echo message = "value = ${param2}"/>
          <ac:var name="param1" unset="true"/>
          <ac:var name="param2" unset="true"/>
          </ac:sequential>
          </ac:for>
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-02-22
            • 2012-11-15
            • 1970-01-01
            相关资源
            最近更新 更多