【发布时间】:2023-03-27 16:19:02
【问题描述】:
现在我更清楚地知道发生了什么,所以重写这个:
我有一些 Ant propertyregex 任务,它们从文件中的图像链接中提取三个属性。然后我想用这些来重写链接。
到目前为止,我已经提取了我需要的属性,然后如果我按照 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>。
【问题讨论】:
-
However now, without the <fileset>, the build just ignores the <replaceregexp> section.. 那是因为你没有给<replaceregexp>任务提供任何输入来匹配-n-replace(<fileset>之前以文件形式提供输入以进行操作)。所以,这样做:<replaceregexp file="${basedir}/inputLog.log" byline="true">..</..>或删除<fileset>和 可选 更改为<include name="inputLog.log/> -
我建议早先删除
<fileset>以避免处理那里的额外文件(相关的inputLog.log和此类文件除外)。如果一个/多个文件需要替换,请注意<include>标记,尽量避免驻留在fileset basedir中的不需要的.log文件。 -
您可以将
regex pattern更改为直接匹配@{line}:<replaceregexp file="..." byline="true"> <regexp pattern="@{line}"/>...并包含override="true" -
另外,我必须说这种方法可行(可能需要稍作调整),但我不会向您推荐。
<propertyregex>在${file}上循环,在<for>循环的每个 迭代中,<replaceregexp>扫描它的输入文件 i> 逐行直到达到匹配/文件结尾。 分组方法可以完全避免这些额外的迭代 -
好的,感谢您的帮助。我现在知道了。我将使用分组方法——事实上,在仅使用 replaceregex 发布问题之前,我已经有了一个解决方案,不涉及属性,但正如我所说,我想学习如何使用属性来做到这一点,或者看看我是否可以。我最初的解决方案采用了多个 replaceregex 操作,所以你的分组想法更好,我会使用它。我将继续尝试使用属性方法,因为这是一种学习体验。再次感谢。
标签: regex ant ant-contrib