Mengganti karakter di properti Ant


90

Adakah cara sederhana untuk mengambil nilai sebuah properti dan kemudian menyalinnya ke properti lain dengan mengganti karakter tertentu?

Katakan propA=This is a value. Saya ingin mengganti semua spasi di dalamnya menjadi garis bawah, menghasilkan propB=This_is_a_value.

Jawaban:


89

Gunakan tugas propertyregex dari Ant Contrib .

Saya pikir Anda ingin:

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

Sayangnya contoh yang diberikan tidak terlalu jelas, tetapi patut dicoba. Anda juga harus memeriksa apa yang terjadi jika tidak ada garis bawah - Anda mungkin perlu menggunakan defaultValueopsi ini juga.


3
Menambahkan defaultValue="${propA}"sempurna sebagai pencarian umum / ganti satu baris: jika tidak, jika tidak ada yang cocok, tidak ada yang dimasukkan ke propB !! Terima kasih!
David Robson

107

Berikut solusinya tanpa scripting dan tidak ada stoples eksternal seperti ant-conrib:

Triknya adalah dengan menggunakan sumber daya ANT:

  • Ada satu jenis sumber daya yang disebut "propertyresource" yang seperti file sumber, tetapi menyediakan aliran dari nilai string sumber daya ini. Jadi Anda dapat memuatnya dan menggunakannya dalam tugas apa pun seperti "salin" yang menerima file
  • Ada juga tugas "loadresource" yang dapat memuat sumber daya apa pun ke properti (misalnya, file), tetapi tugas ini juga dapat memuat sumber daya properti kita. Tugas ini memungkinkan pemfilteran input dengan menerapkan beberapa transformasi token. Akhirnya yang berikut ini akan melakukan apa yang Anda inginkan:
<loadresource property="propB">
  <propertyresource name="propA"/>
  <filterchain>
    <tokenfilter>
      <filetokenizer/>
      <replacestring from=" " to="_"/>
    </tokenfilter>
  </filterchain>
</loadresource>

Yang ini akan mengganti semua "" di propA dengan "_" dan menempatkan hasilnya di propB. "filetokenizer" memperlakukan seluruh aliran input (properti kami) sebagai satu token dan menerapkan penggantian string di atasnya.

Anda dapat melakukan transformasi mewah lainnya menggunakan tokenfilters lain: http://ant.apache.org/manual/Types/filterchain.html


7
Terima kasih! Ternyata Anda bahkan bisa menjatuhkannya <filetokenizer/>sedikit. Kode Anda berfungsi dengan baik tanpanya (setidaknya di Ant v1.8.3).
Matthias

Jika Anda mencoba melakukan ini dari dalam Maven, lihat stackoverflow.com/a/22969187/2163960
user2163960

3
Beri suara positif untuk teknik yang berfungsi di vanilla antdan tidak memerlukan pustaka tambahan.
Christopher Schultz

57

Jika ant-contrib bukan pilihan, berikut adalah solusi portabel untuk Java 1.6 dan yang lebih baru:

<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
Jika metode ini digunakan, alangkah baiknya untuk menyertakan skrip dalam CDATA untuk menghindari masalah dengan penguraian xml. <script language = "javascript"> <! [CDATA [// kode java script dapat menggunakan karakter '<' dengan aman. ]]> </script>
Jan Arciuchiewicz

3
@dnault Javascript tidak memiliki replaceAllfungsi untuk string. Gunakan before.replace( /\s/g, "_" )sebagai gantinya.
Larry Battle

3
@LarryBattle project.getProperty()mengembalikan a java.lang.String, jadi replaceAll()cocok dalam kasus ini. Jika Anda ingin menggunakan replace(), Anda dapat mengonversi 'sebelum' menjadi string JavaScript asli dengan:before = new String(before);
dnault

1
project.setNewPropertyakan lebih portabel, karena setPropertydapat menimpa nilai properti lama. Ia bahkan bisa menulis ke beforeproperti.
Jarekczek

Dibutuhkan Rhino
vintproykt

26

Jika anda ingin solusi yang tidak menggunakan Ant built-in hanya , pertimbangkan ini:

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

Outputnya adalah ${propB} = "This_is_a_value"


2
Siapa yang membersihkan some.tmp.file?
ceving

Karena orang lain mungkin ingin menggunakan ini; Tambahkan <delete file = "some.tmp.file" /> setelah </loadfile>. Jawaban @ceving Pertanyaan :)
terix2k11

8

Gunakan beberapa aplikasi eksternal seperti sed:

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

Jika Anda menjalankan Windows, dapatkan itu googling untuk "gnuwin32 sed".

Perintah s/_/./gmenggantikan setiap _dengan . Skrip ini berjalan dengan baik di bawah jendela. Di bawah linux arg mungkin perlu kutipan.


8

Dua kemungkinan:

melalui tugas skrip dan mesin javascript bawaan (jika menggunakan 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>

atau menggunakan Ant addon 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>

untuk menimpa properti propA yang ada cukup ganti propB dengan propA


7

Berikut adalah versi jawaban Uwe Schindler yang lebih umum :

Anda dapat menggunakan a macrodefuntuk membuat tugas kustom.

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

Anda dapat menggunakan ini sebagai berikut:

<replaceproperty src="property1" dest="property2" replace=" " with="_"/>

ini akan sangat berguna jika Anda melakukan ini beberapa kali


3

Menambahkan contoh jawaban yang lebih lengkap dari jawaban sebelumnya

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

1

Hanya FYI untuk jawaban Mengganti karakter di properti Ant - jika Anda mencoba menggunakan ini di dalam eksekusi maven, Anda tidak dapat mereferensikan variabel maven secara langsung. Anda akan membutuhkan sesuatu seperti ini:

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

Bagian apa yang terkait dengan mengganti " "ke "_"?
Jin Kwon

Atau di maven, Anda dapat menghindari kebutuhan untuk menggunakan properti propATemp dengan mengganti <propertyresource name="propATemp"/>dengan<string value="${propA}"/>
Ed Randall

1

Properti tidak dapat diubah tetapi vars antContrib ( http://ant-contrib.sourceforge.net/tasks/tasks/variable_task.html ) bisa.

Berikut adalah makro untuk melakukan pencarian / penggantian pada 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>

Kemudian panggil makro seperti:

<ac:var name="updatedText" value="${oldText}"/>
<current:replaceVarText varName="updatedText" from="." to="_" />
<echo message="Updated Text will be ${updatedText}"/>

Kode di atas menggunakan javascript split kemudian join, yang lebih cepat dari regex. properti "lokal" diteruskan ke JavaScript sehingga tidak ada kebocoran properti.


0

Atau ... Anda juga dapat mencoba Tugas Anda Sendiri

KODE JAWA:

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

SKRIP SEMUT

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

MENGHIBUR:

run:
     [echo] propA=This is a value
     [echo] propB=This_is_a_value
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.