2009-07-24 13 views
81

¿Existe una manera simple de tomar el valor de una propiedad y luego copiarlo en otra propiedad con ciertos caracteres reemplazados?Reemplazar caracteres en la propiedad Ant

Diga propA=This is a value. Quiero reemplazar todos los espacios en subrayados, lo que resulta en propB=This_is_a_value.

Respuesta

86

Utilice la tarea propertyregex desde Ant Contrib.

Creo que desee:

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

Desafortunadamente los ejemplos dados no son muy claras, pero vale la pena probar eso. También debe verificar lo que sucede si no hay guiones bajos: es posible que necesite usar la opción defaultValue también.

+1

Adición 'defaultValue = "$ {propa}"' es perfecto como una búsqueda general/reemplazo de una línea: de lo contrario, si no hay coincidencia, ¡nada se pone en propB! ¡Gracias! –

8

usan alguna aplicación externa como sed:

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

Si ejecuta Windows consiguen google para "GnuWin32 sed".

El comando s/_/./g reemplaza cada _ con . Este script va bien debajo de las ventanas. Bajo linux arg puede ser necesario citar.

26

En caso de que quiera una solución que utilice Ant empotrados única, considere esto:

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

salida es ${propB} = "This_is_a_value"

+2

¿Quién limpia algún archivo.tmp.? – ceving

+0

Dado que otros pueden desear usar esto; Agregue después de. Respuestas @ceving Pregunta :) – terix2k11

51

Si ant-contrib no es una opción, aquí hay una solución portátil para Java 1.6 y posteriores:

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

Si se utiliza este método, sería bueno incluir el script en CDATA para evitar problemas con el análisis xml.

+3

@dnault Javascript no tiene una función 'replaceAll' para cuerdas. Use 'before.replace (/ \ s/g," _ ")' en su lugar. –

+3

@LarryBattle 'project.getProperty()' devuelve un 'java.lang.String', por lo que' replaceAll() 'es apropiado en este caso. Si quisiera usar 'replace()', podría convertir 'before' a una cadena de JavaScript nativa con: 'before = new String (before);' – dnault

8

dos posibilidades:

a través de la tarea de la escritura y el motor JavaScript incorporado (si se utiliza 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> 

o el uso de 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> 

sobrescribir exisiting propiedad propA simplemente reemplazar propB con propA

84

Aquí está la solución sin scripts y sin archivos externos como ant-conrib:

El truco es utilizar los recursos de ANT:

  • Hay un tipo de recurso denominado "propertyresource", que es como un archivo de origen, sino que proporciona un flujo de la cadena de valor de este recurso. Entonces puede cargarlo y usarlo en cualquier tarea como "copiar" que acepte archivos
  • También existe la tarea "loadresource" que puede cargar cualquier recurso a una propiedad (por ejemplo, un archivo), pero este también podría cargar nuestro recurso de propiedad Esta tarea permite filtrar la entrada aplicando algunas transformaciones de token.Por último, el siguiente va a hacer lo que quiere:
<loadresource property="propB"> 
    <propertyresource name="propA"/> 
    <filterchain> 
    <tokenfilter> 
     <filetokenizer/> 
     <replacestring from=" " to="_"/> 
    </tokenfilter> 
    </filterchain> 
</loadresource> 

Ésta se sustituirá todo "" en propA por "_" y colocar el resultado en propB. "filetokenizer" trata el flujo de entrada completo (nuestra propiedad) como un token y solicita el reemplazo de cadena en él.

Usted puede hacer otras transformaciones de lujo utilizando otros tokenfilters: http://ant.apache.org/manual/Types/filterchain.html

+4

Gracias! Resulta que incluso puedes soltar el bit ''. Tu código funciona bien sin él (al menos en Ant v1.8.3). – Matthias

+0

Si está tratando de hacer esto desde dentro de Maven, consulte http://stackoverflow.com/a/22969187/2163960 – user2163960

+1

Upvote para una técnica que funciona en 'ant' de vainilla y no requiere bibliotecas adicionales. –

1

Sólo una intensa respuesta de Replacing characters in Ant property - si usted está tratando de utilizar esto dentro de una ejecución experta, no se puede hacer referencia a variables de Maven directamente. Se necesita algo como esto:

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

¿Qué partes se relacionan con reemplazar '" "' a '" _ "'? –

+0

Alternativamente en maven, puede evitar la necesidad de usar la propiedad 'propATemp' reemplazando' 'con' ' –

4

Aquí hay una versión más generalizada de Uwe Schindler's answer:

Puede utilizar un macrodef para crear una tarea personalizada.

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

puede utilizar esto como sigue:

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

esto va a ser muy útil si usted está haciendo esto varias veces

0

O ... También puede probar Your Own Task

CÓDIGO DE 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> 

CONSOLA:

run: 
    [echo] propA=This is a value 
    [echo] propB=This_is_a_value 
2

Adición de una respuesta ejemplo más completo sobre un previous answer

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