En Python, al formatear una cadena, puedo llenar marcadores de posición por nombre en lugar de por posición, así:
print "There's an incorrect value '%(value)s' in column # %(column)d" % \
{ 'value': x, 'column': y }
Me pregunto si eso es posible en Java (con suerte, sin bibliotecas externas).
java
string-formatting
Andy
fuente
fuente
%s
era una práctica común. en.wikipedia.org/wiki/Printf_format_string#History También tenga en cuenta que algunos IDE y FindBugs pueden detectar automáticamente los recuentos% s y% d que no coinciden, pero aún así preferiría los campos con nombre.Respuestas:
StrSubstitutor of jakarta commons lang es una forma ligera de hacerlo siempre que sus valores ya estén formateados correctamente.
http://commons.apache.org/proper/commons-lang/javadocs/api-3.1/org/apache/commons/lang3/text/StrSubstitutor.html
Los resultados anteriores en:
"Hay un valor incorrecto '1' en la columna # 2"
Cuando use Maven, puede agregar esta dependencia a su pom.xml:
fuente
${arg}
) en lugar de la personalizada anterior (%(arg)
), la expresión regular no se compilará, que es el efecto deseado.no del todo, pero puede usar MessageFormat para hacer referencia a un valor varias veces:
Lo anterior también se puede hacer con String.format (), pero encuentro limpiador de sintaxis messageFormat si necesita construir expresiones complejas, además no necesita preocuparse por el tipo de objeto que está poniendo en la cadena
fuente
MessageFormat
es genial pero engorroso para contenido json relativamente grandeOtro ejemplo de Apache Common StringSubstitutor para marcador de posición simple nombrado.
fuente
replaceIn
valores sustitutivos en un búfer: StringBuilder o TextStringBuilder. Con este enfoque, todo el contenido del archivo no se cargará en la memoria.Puede usar la biblioteca StringTemplate , ofrece lo que desea y mucho más.
fuente
'
unexpected char: '''
Para casos muy simples , simplemente puede usar un reemplazo de cadena codificado, sin necesidad de una biblioteca allí:
ADVERTENCIA : solo quería mostrar el código más simple posible. Por supuesto, NO use esto para un código de producción serio donde la seguridad es importante, como se indica en los comentarios: el escape, el manejo de errores y la seguridad son un problema aquí. Pero en el peor de los casos, ahora sabe por qué se requiere el uso de una 'buena' lib :-)
fuente
¡Gracias por toda tu ayuda! Usando todas sus pistas, he escrito la rutina para hacer exactamente lo que quiero: formateo de cadena similar a python usando el diccionario. Como soy novato en Java, cualquier sugerencia es apreciada.
fuente
formatPos
que no puede contenerformatKey
.Este es un hilo antiguo, pero solo para el registro, también podría usar el estilo Java 8, como este:
Uso:
La salida será:
fuente
.reduce()
trata los resultados de sustitución intermedia como cadenas de formato propias, esta solución es vulnerable a los ataques de cadenas de formato . Cualquier solución correcta debe hacer una sola pasada a través de la cadena de formato.Ejemplo:
fuente
.replaceAll()
devoluciones de llamada de sustitución de cadenas .Soy el autor de una pequeña biblioteca que hace exactamente lo que quieres:
O puedes encadenar los argumentos:
fuente
El método replaceEach de Apache Commons Lang puede ser útil dependiendo de sus necesidades específicas. Puede usarlo fácilmente para reemplazar marcadores de posición por nombre con esta llamada de método único:
Dado un poco de texto de entrada, esto reemplazará todas las apariciones de los marcadores de posición en el primer conjunto de cadenas con los valores correspondientes en el segundo.
fuente
Podría tener algo como esto en una clase auxiliar de cadena
fuente
Mi respuesta es:
a) use StringBuilder cuando sea posible
b) mantenga la posición del "marcador de posición" (en cualquier forma: entero es el mejor, especialmente como macro de dólar, etc.) y luego use
StringBuilder.insert()
(pocas versiones de argumentos).El uso de bibliotecas externas parece excesivo y creo que el rendimiento de degradación es significativo, cuando StringBuilder se convierte a String internamente.
fuente
Según la respuesta , creé la
MapBuilder
clase:Luego creé la clase
StringFormat
para el formato de cadena:que podrías usar así:
fuente
También creé una clase util / helper (usando jdk 8) que puede formatear una cadena y reemplaza las ocurrencias de variables.
Para este propósito, utilicé el método "appendReplacement" de Matchers que realiza todas las sustituciones y bucles solo sobre las partes afectadas de una cadena de formato.
La clase auxiliar actualmente no está bien documentada por javadoc. Cambiaré esto en el futuro;) De todos modos, comenté las líneas más importantes (espero).
Puede crear una instancia de clase para un Mapa específico con valores (o sufijo prefijo o noKeyFunction) como:
Además, puede definir qué sucede si falta una clave en el mapa de valores (funciona en ambos sentidos, por ejemplo, nombre de variable incorrecto en la cadena de formato o clave faltante en el mapa). El comportamiento predeterminado es una excepción no marcada (sin marcar porque uso la función jdk8 predeterminada que no puede manejar excepciones marcadas) como:
Puede definir un comportamiento personalizado en la llamada del constructor como:
o delegarlo de nuevo al comportamiento predeterminado sin clave:
Para un mejor manejo también hay representaciones de métodos estáticos como:
fuente
No hay nada integrado en Java al momento de escribir esto. Sugeriría escribir su propia implementación. Mi preferencia es una interfaz de generador de fluidos simple en lugar de crear un mapa y pasarlo a la función; terminas con un buen fragmento de código contiguo, por ejemplo:
Aquí hay una implementación simple:
fuente
Prueba Freemarker , biblioteca de plantillas.
fuente
https://dzone.com/articles/java-string-format-examples String.format (inputString, [listOfParams]) sería la forma más fácil. Los marcadores de posición en cadena se pueden definir por orden. Para más detalles, consulte el enlace proporcionado.
fuente
Deberías echar un vistazo a la biblioteca oficial ICU4J . Proporciona un MessageFormat clase similar a la disponible con el JDK, pero esta primera admite marcadores de posición con nombre.
A diferencia de otras soluciones proporcionadas en esta página. ICU4j es parte del proyecto ICU que mantiene IBM y lo actualiza regularmente. Además, admite casos de uso avanzados como la pluralización y mucho más.
Aquí hay un ejemplo de código:
fuente
Hay Java Plugin para usar la interpolación de cadenas en Java (como en Kotlin, JavaScript). Es compatible con Java 8, 9, 10, 11 ... https://github.com/antkorwin/better-strings
Usar variables en literales de cadena:
Usando expresiones:
Usando funciones:
Para obtener más información, lea el proyecto README.
fuente