是否有一种简单的方法来获取属性的值,然后将其复制到替换了某些字符的另一个属性中?
说propA=This is a value
。我想将其中的所有空格替换为下划线,结果为propB=This_is_a_value
。
Answers:
使用Ant Contrib的propertyregex任务。
我想你要:
<propertyregex property="propB"
input="${propA}"
regexp=" "
replace="_"
global="true" />
不幸的是,给出的例子还不是很清楚,但是值得尝试。您还应该检查如果没有任何下划线,会发生什么情况-您可能还需要使用该defaultValue
选项。
这是没有脚本并且没有像ant-conrib这样的外部jar的解决方案:
诀窍是使用ANT的资源:
<loadresource property="propB">
<propertyresource name="propA"/>
<filterchain>
<tokenfilter>
<filetokenizer/>
<replacestring from=" " to="_"/>
</tokenfilter>
</filterchain>
</loadresource>
这将用“ _”替换propA中的所有“”并将结果放入propB中。“ filetokenizer”将整个输入流(我们的属性)视为一个令牌,并在其上加上字符串替换。
您可以使用其他令牌过滤器进行其他精美的转换:http ://ant.apache.org/manual/Types/filterchain.html
<filetokenizer/>
位。没有它,您的代码就可以正常工作(至少在Ant v1.8.3上)。
ant
且不需要其他库的技术。
如果不能选择ant-contrib,那么这是Java 1.6及更高版本的可移植解决方案:
<property name="before" value="This is a value"/>
<script language="javascript">
var before = project.getProperty("before");
project.setProperty("after", before.replaceAll(" ", "_"));
</script>
<echo>after=${after}</echo>
replaceAll
字符串功能。使用before.replace( /\s/g, "_" )
代替。
project.getProperty()
返回a java.lang.String
,因此replaceAll()
在这种情况下是合适的。如果要使用replace()
,则可以使用以下命令将“之前”转换为本地JavaScript字符串:before = new String(before);
project.setNewProperty
会更容易移植,因为setProperty
可能会覆盖旧的属性值。它甚至可以写入before
属性。
如果您想要一个仅使用Ant内置组件的解决方案,请考虑以下事项:
<target name="replace-spaces">
<property name="propA" value="This is a value" />
<echo message="${propA}" file="some.tmp.file" />
<loadfile property="propB" srcFile="some.tmp.file">
<filterchain>
<tokenfilter>
<replaceregex pattern=" " replace="_" flags="g"/>
</tokenfilter>
</filterchain>
</loadfile>
<echo message="$${propB} = "${propB}"" />
</target>
输出是 ${propB} = "This_is_a_value"
两种可能性:
通过脚本任务和内置的javascript引擎(如果使用jdk> = 1.6)
<project>
<property name="propA" value="This is a value"/>
<script language="javascript">
project.setProperty('propB', project.getProperty('propA').
replace(" ", "_"));
</script>
<echo>$${propB} => ${propB}</echo>
</project>
或使用Ant插件Flaka
<project xmlns:fl="antlib:it.haefelinger.flaka">
<property name="propA" value="This is a value"/>
<fl:let> propB := replace('${propA}', '_', ' ')</fl:let>
<echo>$${propB} => ${propB}</echo>
</project>
覆盖现有属性propA只需将propB替换为propA
这是Uwe Schindler的答案的更一般化的版本:
您可以使用macrodef
来创建自定义任务。
<macrodef name="replaceproperty" taskname="@{taskname}">
<attribute name="src" />
<attribute name="dest" default="" />
<attribute name="replace" default="" />
<attribute name="with" default="" />
<sequential>
<loadresource property="@{dest}">
<propertyresource name="@{src}" />
<filterchain>
<tokenfilter>
<filetokenizer/>
<replacestring from="@{replace}" to="@{with}"/>
</tokenfilter>
</filterchain>
</loadresource>
</sequential>
</macrodef>
您可以按以下方式使用它:
<replaceproperty src="property1" dest="property2" replace=" " with="_"/>
如果您多次这样做,这将非常有用
只是一个供您回答的FYI 替换Ant属性中的字符 -如果您试图在maven执行中使用它,则不能直接引用maven变量。您将需要以下内容:
...
<target>
<property name="propATemp" value="${propA}"/>
<loadresource property="propB">
<propertyresource name="propATemp" />
...
" "
来"_"
?
propATemp
通过<propertyresource name="propATemp"/>
使用<string value="${propA}"/>
属性不能更改,但antContrib vars(http://ant-contrib.sourceforge.net/tasks/tasks/variable_task.html)可以更改。
这是在var上查找/替换的宏:
<macrodef name="replaceVarText">
<attribute name="varName" />
<attribute name="from" />
<attribute name="to" />
<sequential>
<local name="replacedText"/>
<local name="textToReplace"/>
<local name="fromProp"/>
<local name="toProp"/>
<property name="textToReplace" value = "${@{varName}}"/>
<property name="fromProp" value = "@{from}"/>
<property name="toProp" value = "@{to}"/>
<script language="javascript">
project.setProperty("replacedText",project.getProperty("textToReplace").split(project.getProperty("fromProp")).join(project.getProperty("toProp")));
</script>
<ac:var name="@{varName}" value = "${replacedText}"/>
</sequential>
</macrodef>
然后像这样调用宏:
<ac:var name="updatedText" value="${oldText}"/>
<current:replaceVarText varName="updatedText" from="." to="_" />
<echo message="Updated Text will be ${updatedText}"/>
上面的代码使用javascript split然后加入,比regex快。“本地”属性将传递给JavaScript,因此不会发生属性泄漏。
或者...您也可以尝试自己的任务
JAVA代码:
class CustomString extends Task{
private String type, string, before, after, returnValue;
public void execute() {
if (getType().equals("replace")) {
replace(getString(), getBefore(), getAfter());
}
}
private void replace(String str, String a, String b){
String results = str.replace(a, b);
Project project = getProject();
project.setProperty(getReturnValue(), results);
}
..all getter and setter..
蚂蚁脚本
...
<project name="ant-test" default="build">
<target name="build" depends="compile, run"/>
<target name="clean">
<delete dir="build" />
</target>
<target name="compile" depends="clean">
<mkdir dir="build/classes"/>
<javac srcdir="src" destdir="build/classes" includeantruntime="true"/>
</target>
<target name="declare" depends="compile">
<taskdef name="string" classname="CustomString" classpath="build/classes" />
</target>
<!-- Replacing characters in Ant property -->
<target name="run" depends="declare">
<property name="propA" value="This is a value"/>
<echo message="propA=${propA}" />
<string type="replace" string="${propA}" before=" " after="_" returnvalue="propB"/>
<echo message="propB=${propB}" />
</target>
安慰:
run:
[echo] propA=This is a value
[echo] propB=This_is_a_value
defaultValue="${propA}"
作为一般的搜索/替换单行代码,添加是完美的:否则,如果没有匹配项,则propB中什么都不会放入!谢谢!