Antプロパティの文字を置き換える


90

プロパティの値を取得し、特定の文字を置き換えて別のプロパティにコピーする簡単な方法はありますか?

言ってくださいpropA=This is a value。私は、その結果、アンダースコアにその中のすべてのスペースを置き換えたいですpropB=This_is_a_value

回答:


89

Ant Contribのpropertyregexタスクを使用します

私はあなたが望むと思います:

<propertyregex property="propB"
               input="${propA}"
               regexp=" "
               replace="_"
               global="true" />

残念ながら、与えられた例はひどく明確ではありませんが、それを試す価値はあります。また、アンダースコアがない場合はどうなるかを確認する必要がありdefaultValueます。オプションを使用する必要がある場合もあります。


3
追加defaultValue="${propA}"は、一般的な検索/置換のワンライナーとして完璧です。それ以外の場合、一致がない場合、propBには何も入力されません。ありがとう!
David Robson

107

スクリプトなしのソリューションであり、ant-conribのような外部jarはありません。

コツは、ANTのリソースを使用することです。

  • ソースファイルのような「propertyresource」と呼ばれる1つのリソースタイプがありますが、このリソースの文字列値からストリームを提供します。ロードして、ファイルを受け入れる「コピー」などのタスクで使用できます。
  • プロパティ(ファイルなど)に任意のリソースをロードできるタスク「loadresource」もありますが、これはpropertyresourceをロードすることもできます。このタスクでは、いくつかのトークン変換を適用して、入力をフィルタリングできます。最後に、以下はあなたが望むことをします:
<loadresource property="propB">
  <propertyresource name="propA"/>
  <filterchain>
    <tokenfilter>
      <filetokenizer/>
      <replacestring from=" " to="_"/>
    </tokenfilter>
  </filterchain>
</loadresource>

これは、propAのすべての ""を "_"に置き換え、結果をpropBに配置します。「filetokenizer」は、入力ストリーム全体(プロパティ)を1つのトークンとして扱い、それに文字列置換を適用します。

他のtokenfiltersを使用して他の空想的な変換を行うことができます:http ://ant.apache.org/manual/Types/filterchain.html


7
ありがとう!<filetokenizer/>少し落とすことさえできることがわかりました。コードはそれなしでも問題なく機能します(少なくともAnt v1.8.3では)。
Matthias

あなたはMavenの中からこれを実行しようとしている場合は、参照stackoverflow.com/a/22969187/2163960
user2163960

3
バニラantで機能し、追加のライブラリを必要としないテクニックに賛成票を投じてください。
クリストファーシュルツ

57

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>

6
この方法を使用する場合は、XML解析の問題を回避するために、スクリプトをCDATAで囲むとよいでしょう。<script language = "javascript"> <![CDATA [// Javaスクリプトコードは「<」文字を安全に使用できます。]]> </ script>
Jan Arciuchiewicz

3
@dnault JavascriptにはreplaceAll文字列用の関数がありません。before.replace( /\s/g, "_" )代わりに使用してください。
ラリーバトル

3
@LarryBattle project.getProperty()はを返すjava.lang.StringのでreplaceAll()、この場合は適切です。あなたが使用したい場合replace()、あなたはネイティブJavaScriptの文字列にして「前に」変換することができます:before = new String(before);
dnault

1
project.setNewPropertysetProperty古いプロパティ値を上書きできるため、移植性が向上します。beforeプロパティに書き込むこともできます。
Jarekczek 2012年

Rhinoが必要です
vintproykt

26

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} = &quot;${propB}&quot;" />
</target>

出力は ${propB} = "This_is_a_value"


2
だれがsome.tmp.fileをクリーンアップしますか?
2014年

他の人がこれを使いたいかもしれないので; <delete file = "some.tmp.file" />を</ loadfile>の後に追加します。@ceving質問への回答:)
terix2k11

8

sedなどの外部アプリを使用します。

<exec executable="sed" inputstring="${wersja}" outputproperty="wersjaDot">
  <arg value="s/_/./g"/>
</exec>
<echo>${wersjaDot}</echo>

Windowsを実行している場合は、「gnuwin32 sed」を検索してください。

このコマンドs/_/./gはすべて_. このスクリプトに置き換えます。このスクリプトはWindowsでもうまく機能します。Linuxでは、argは引用符で囲む必要があります。


8

2つの可能性:

スクリプトタスクと組み込みの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に置き換えるだけです


7

これは、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="_"/>

これを複数回実行している場合、これは非常に便利です。


3

前の回答よりも完全な例の回答を追加する

<property name="propB_" value="${propA}"/>
<loadresource property="propB">
  <propertyresource name="propB_" />
  <filterchain>
    <tokenfilter>
      <replaceregex pattern="\." replace="/" flags="g"/>
    </tokenfilter>
  </filterchain>
</loadresource>

1

Antプロパティの文字を置き換えるための参考情報-Maven実行内でこれを使用しようとしている場合、Maven変数を直接参照することはできません。次のようなものが必要になります。

...
<target>
<property name="propATemp" value="${propA}"/>
    <loadresource property="propB">
    <propertyresource name="propATemp" />
...

交換" "に関連するパーツは何"_"ですか?
Jin Kwon

代わりのmavenで、あなたは利用プロパティへの必要性を回避することができるpropATemp 置き換えることで<propertyresource name="propATemp"/><string value="${propA}"/>
エド・ランドール

1

プロパティは変更できませんが、antContrib変数(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 then joinを使用しています。「ローカル」プロパティはJavaScriptに渡されるため、プロパティリークはありません。


0

または... 自分のタスクを試すこともできます

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..

ANT SCRIPT

...
<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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.