现在我更清楚地知道发生了什么:
我有一些Ant属性gex任务,它们从文件中的图像链接中提取三个属性。然后我想用这些来重写链接。
到目前为止,我已经提取了我需要的属性,然后如果我用replaceregex任务来完成,我可以使用这些属性来重写链接。然而,即使replaceregex将一次操作一行,完成一行,然后从下一行开始,它也会获取从第一个链接提取的属性,并将它们用作文件中每个链接的替换项。
有没有办法将这两者结合起来,使整个操作从一个链接开始,提取属性,重写它,然后移动到下一个链接,重新开始所有操作?
这是我得到的:
<project name="BuildModule" basedir="." default="extract.stuff">
<taskdef resource="net/sf/antcontrib/antlib.xml" />
<property environment="env" />
<loadfile property="file" srcfile="${basedir}/inputLog.log"/>
<target name="extract.stuff">
<for param="line" delimiter="${line.separator}" list="${file}">
<sequential>
<propertyregex property="imageName" input="@{line}" regexp="(<img class.*?graphics/)(.*?jpg|png)" select="2" />
<propertyregex property="width" input="@{line}" regexp="(<img class)(.*?)(width.*?)(alt)" select="3" />
<propertyregex property="alt" input="@{line}" regexp="(<img class)(.*?)(width.*?)(alt=)(.*?)(/>)" select="5" />
</sequential>
</for>
<replaceregexp byline="true">
<regexp pattern="(<img class)(.*?$)"/>
<substitution expression="<ac:image ac:title=${alt} ac:${width}><ri:attachment ri:filename="${imageName}"><ri:page ri:content-title="acme_shared_graphics" /></ri:attachment></ac:image></p>"/>
<fileset dir=".">
<include name="**.log"/>
</fileset>
</replaceregexp>
</target>
输入文件中的链接如下:
<p class="p"><img class="image" id="concept_kdv_4zf_k4__image_qt1_pvc_q4" src="../../../shared_assets/acme_shared_graphics/acme_image_test.jpg" width="400" alt="Some alt title text"/></p>
结果是:
<p class="p"><ac:image ac:title="Some alt title text" ac:width="400" ><ri:attachment ri:filename="acme_image_test.jpg"><ri:page ri:content-title="acme_shared_graphics" /></ri:attachment></ac:image></p>
一旦我开始工作,我希望(.*?jpg|png)
选项也能工作,根据链接所包含的内容提取image_name.jpg
或image_name.png
,然后以相同的方式替换它。
更新
以下是我现在得到的帮助:
<project name="BuildModule" basedir="." default="extract.stuff">
<taskdef resource="net/sf/antcontrib/antlib.xml" />
<property environment="env" />
<loadfile property="file" srcfile="${basedir}/inputLog.log"/>
<target name="extract.stuff">
<for param="line" delimiter="${line.separator}" list="${file}">
<sequential>
<propertyregex override="true" property="imageName" input="@{line}" regexp="(<img class.*?graphics/)(.*?jpg|png)" select="2" />
<propertyregex override="true" property="width" input="@{line}" regexp="(<img class)(.*?)(width.*?)(alt)" select="3" />
<propertyregex override="true" property="alt" input="@{line}" regexp="(<img class)(.*?)(width.*?)(alt=)(.*?)(/>)" select="5" />
<replaceregexp byline="true">
<regexp pattern="(<img class)(.*?$)"/>
<substitution expression="<ac:image ac:title=${alt} ac:${width}><ri:attachment ri:filename="${imageName}"><ri:page ri:content-title="BSW_shared_graphics" /></ri:attachment></ac:image></p>"/>
<!--
<fileset dir=".">
<include name="**.log"/>
</fileset>
-->
</replaceregexp>
</sequential>
</for>
</target>
在<replaceregexp>
中注释掉<fileset></fileset>
是为了让一切都按照<for>
循环中指定的输入运行,因为问题是使用文件集的<replaceregexp>
在返回<propertyregex>
部分之前逐行处理整个文件。然而,现在,如果没有<fileset>
,构建只会忽略<replaceregexp>
部分。如果我将<fileset>
放回,它的作用与以前一样,将每个属性更改为文件中遇到的第一个属性。
向<propertyregex>
添加覆盖修复了保留属性的问题,因此我不需要<unset>
。
<for>
循环在<replaceregexp>
之前已经结束,因此您并没有真正为<replaceregexp>
任务的每一行提取${imageName}, ${width} and ${alt}
的值。因此,它们不会改变,并且可能会由于缺少override="true"
而保留<propertyregex>
通过的FIRST行的值。
因此,如下一个答案所示,在<for><sequential></..></..>
中包含<replaceregexp>
任务,或者,不在<substitution>
表达式中指定imageName, width and alt
。。。指定组,如2, 5, X..
,并将<regex>
模式字符串替换为包含文件整行的字符串。
例如:
<regexp pattern="<img class.*?/(.*?graphics)/(.*?)" width="(.*?)" -alt="(.*?)"/>"/>
<substitution expression="<ac:image ac:title="4" ac:"3"><ri:attachment ri:filename="2"><ri:page ri:content-title="1" /></ri:attachment></ac:image></p>"/>
编辑:
propertyregex
已经允许属性的可变性。因此,imageName, alt and width
是可以更改的(只需添加override="true"
作为属性-<propertyregex ... override="true".../>
,就不需要任何unset="true"
(。
imageName, alt and width
只得到first line values for every line
的原因是<propertyregex>
缺少override="true"
,因此在第一次设置这些属性时,它们在<for>
的后续循环中保持不变所以现在,
--将CCD_ 36包括在CCD_
--将override
添加到所有三个属性中:<propertyregex .. override="true".. />
(此外,您当前的<replaceregexp>
为所有<fileset>
中的文件运行。如果您将其包含在<sequential>
中,请确保避免fileset basedir
中不相关的文件被<include name= regex>
拾取(
它应该起作用。
OR,尝试我提到的grouping
方法。我会选择这个的。在这里,我认为您根本不需要任何<for> & <propertyregexp>
。只需在整个<fileset>
上运行(在target
内(only<replaceregexp>
任务,就像您所做的那样,但更改<regex pattern
和<substitution expression
以适应分组。
实际上,如果仔细观察,<propertyregex>
所做的只是从其输入行中选择relevant groupings
,并且-<replaceregexp>
的实现将替换文件/行中的这些值通过在<replaceregexp>
任务本身中使用分组来将这两者组合
有关<replaceregexp>
的更多信息,请参阅此处。
在Ant中,一旦设置属性,设计就不可变,因此您需要首先使用antcontrib unset取消设置属性。然后,您将在for循环中使用您的replaceregexp内容:
<for param="line" delimiter="${line.separator}" list="${file}">
<sequential>
<var name="imageName" unset="true"/>
<var name="width" unset="true"/>
<var name="alt" unset="true"/>
<propertyregex property="imageName" input="@{line}" regexp="(<img class.*?graphics/)(.*?jpg|png)" select="2" />
<propertyregex property="width" input="@{line}" regexp="(<img class)(.*?)(width.*?)(alt)" select="3" />
<propertyregex property="alt" input="@{line}" regexp="(<img class)(.*?)(width.*?)(alt=)(.*?)(/>)" select="5" />
<replaceregexp>
<!-- ... -->
</replaceregexp>
</sequential>
</for>