Ant özelliğindeki karakterleri değiştirme


90

Bir mülkün değerini almanın ve ardından onu belirli karakterlerin değiştirildiği başka bir mülke kopyalamanın basit bir yolu var mı?

Söyle propA=This is a value. İçindeki tüm boşlukları alt çizgilerle değiştirmek istiyorum, sonuçta propB=This_is_a_value.

Yanıtlar:


89

Ant Contrib'tan propertyregex görevini kullanın .

Sanırım istiyorsun:

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

Maalesef verilen örnekler çok net değil, ancak bunu denemeye değer. Alt çizgi yoksa ne olacağını da kontrol etmelisiniz - defaultValueseçeneği de kullanmanız gerekebilir .


3
Ekleme defaultValue="${propA}", genel arama / tek satırlık değiştirme olarak mükemmeldir: aksi takdirde, eşleşme yoksa, propB'ye hiçbir şey konmaz !! Teşekkürler!
David Robson

107

İşte komut dosyası olmadan ve ant-conrib gibi harici kavanozlar olmadan çözüm:

İşin püf noktası ANT'nin kaynaklarını kullanmaktır:

  • Bir kaynak dosyası gibi olan, ancak bu kaynağın dize değerinden bir akış sağlayan "özellik kaynağı" adında bir kaynak türü vardır. Böylece onu yükleyebilir ve dosyaları kabul eden "kopyalama" gibi herhangi bir görevde kullanabilirsiniz.
  • Herhangi bir kaynağı bir özelliğe (örneğin bir dosyaya) yükleyebilen "yük kaynağı" görevi de vardır, ancak bu aynı zamanda özellik kaynağımızı da yükleyebilir. Bu görev, bazı belirteç dönüşümleri uygulayarak girdiyi filtrelemeye izin verir. Sonunda aşağıdakiler istediğinizi yapacak:
<loadresource property="propB">
  <propertyresource name="propA"/>
  <filterchain>
    <tokenfilter>
      <filetokenizer/>
      <replacestring from=" " to="_"/>
    </tokenfilter>
  </filterchain>
</loadresource>

Bu, propA'daki tüm "" 'yi "_" ile değiştirecek ve sonucu propB'ye yerleştirecektir. "filetokenizer", tüm girdi akışını (bizim özelliğimiz) tek bir belirteç olarak ele alır ve dize değişimini buna ekler.

Diğer tokenfilters kullanarak başka süslü dönüşümler yapabilirsiniz: http://ant.apache.org/manual/Types/filterchain.html


7
Teşekkürler! Hatta <filetokenizer/>biraz düşebilirsin . Kodunuz onsuz iyi çalışır (en azından Ant v1.8.3'te).
Matthias

Bunu Maven içinden yapmaya çalışıyorsanız, stackoverflow.com/a/22969187/2163960
user2163960

3
Vanilyada çalışan antve ek kitaplıklar gerektirmeyen bir teknik için oy verin .
Christopher Schultz

57

Karınca katkısı bir seçenek değilse, işte Java 1.6 ve sonrası için taşınabilir bir çözüm:

<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
Bu yöntem kullanılırsa, xml çözümlemeyle ilgili sorunları önlemek için komut dizisini CDATA içine almak iyi olacaktır. <script language = "javascript"> <! [CDATA [// java komut dosyası kodu '<' karakterini güvenle kullanabilir. ]]> </script>
Jan Arciuchiewicz

3
@dnault Javascript'in replaceAlldizeler için bir işlevi yoktur. before.replace( /\s/g, "_" )Bunun yerine kullanın .
Larry Battle

3
@LarryBattle a project.getProperty()döndürür java.lang.String, replaceAll()bu durumda bu durumda uygundur. Kullanmak isterse replace(): ile bir yerli JavaScript dize olarak, 'before' dönüştürebilirsinizbefore = new String(before);
dnault

1
project.setNewPropertysetPropertyeski özellik değerinin üzerine yazılabileceği için daha taşınabilir olacaktır . Hatta beforemülke yazabilir .
Jarekczek

Rhino gerektirir
vintproykt

26

Yalnızca Ant yerleşiklerini kullanan bir çözüm istiyorsanız , şunu göz önünde bulundurun:

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

Çıktı ${propB} = "This_is_a_value"


2
Some.tmp dosyasını kim temizler?
2014

Başkaları bunu kullanmak isteyebileceğinden; </loadfile> dosyasından sonra <delete file = "some.tmp.file" /> ekleyin. Cevaplar @ceving Soru :)
terix2k11

8

Sed gibi bazı harici uygulamaları kullanın:

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

Windows'u çalıştırırsanız, "gnuwin32 sed" için googling yapın.

Komut s/_/./gher yerini _ile . bu komut windows altında iyi gider. Linux altında arg, alıntı gerektirebilir.


8

İki olasılık:

komut dosyası görevi ve yerleşik javascript motoru aracılığıyla (jdk> = 1.6 kullanıyorsanız)

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

veya Ant addon Flaka kullanarak

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

mevcut propA özelliğinin üzerine yazmak için propB'yi propA ile değiştirmeniz yeterlidir


7

İşte Uwe Schindler'in cevabının daha genel bir versiyonu :

macrodefÖzel bir görev oluşturmak için a kullanabilirsiniz .

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

bunu aşağıdaki gibi kullanabilirsiniz:

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

Bunu birden çok kez yapıyorsanız bu oldukça faydalı olacaktır.


3

Önceki cevaba göre daha eksiksiz bir örnek eklemek

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

1

Cevap için sadece bir FYI Ant özelliğindeki karakterleri değiştirme - bunu bir maven uygulamasının içinde kullanmaya çalışıyorsanız, maven değişkenlerine doğrudan başvuramazsınız. Bunun gibi bir şeye ihtiyacınız olacak:

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

Değiştirmeyle ilgili parçalar " " ile"_" ?
Jin Kwon

Alternatif olarak maven'de, mülk kullanma ihtiyacınıpropATemp<propertyresource name="propATemp"/><string value="${propA}"/>
Ed Randall

1

Özellikler değiştirilemez, ancak antContrib değişkenleri ( http://ant-contrib.sourceforge.net/tasks/tasks/variable_task.html ) değiştirebilir.

İşte bir var üzerinde bul / değiştir yapmak için bir makro:

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

Ardından makroyu şu şekilde arayın:

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

Yukarıdaki kod, regex'ten daha hızlı olan javascript bölme sonra birleştirme kullanır. "yerel" özellikler JavaScript'e aktarılır, dolayısıyla özellik sızıntısı olmaz.


0

Veya ... Kendi Görevinizi de deneyebilirsiniz

JAVA KODU:

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

KARINCA SENARYOSU

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

KONSOL:

run:
     [echo] propA=This is a value
     [echo] propB=This_is_a_value
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.