通常指的是将任意数量的各种数据类型显示为字符串的许多方法。
有时需要使用类似日志记录的模式组成字符串: 出了点问题,detailA={},detailB={} 但不是为了记录它,而是为了其他目的(例如通过网络发送)。
我有类似的东西: String text = “用户 {0} 的电子邮件地址为 {1}。” // params = { "Robert", "myemailaddr@gmail.com" } String msg = MessageFormat.format(text, params); 这不太适合...
是否有像 String.format 这样的标准或至少广泛的实现,但带有命名参数? 我想以这样的方式格式化模板化字符串: 地图 是否有类似 String.format 之类的标准或至少广泛的实现,但带有命名参数? 我想以这样的方式格式化模板化字符串: Map<String, Object> args = new HashMap<String, Object>(); args.put("PATH", "/usr/bin"); args.put("file", "foo"); String s = someHypotheticalMethod("#{PATH}/ls #{file}"); // "/usr/bin/ls foo" 从技术上讲,它几乎与: String[] args = new String[] { "/usr/bin", "foo" }; String s = String.format("%1$s/ls %2$s", args); // "/usr/bin/ls foo" 但带有命名参数。 我知道: 字符串.format 格式化程序 消息格式 但它们都使用有序或至少编号的参数,而不是命名的参数。我知道实现它很简单,但是我是否在标准 Java 库中或至少在 Apache Commons / Guava / 类似的东西中寻找一种机制,而不引入引人注目的模板引擎? 注意:我对成熟的模板引擎并不真正感兴趣,它具有一些命令式/功能逻辑、流程控制、修饰符、子模板/包含、迭代器等功能。通常以下方法是有效的 4 -line 实现 - 这就是我所需要的: public static String interpolate(String format, Map<String, ? extends Object> args) { String out = format; for (String arg : args.keySet()) { out = Pattern.compile(Pattern.quote("#{" + arg + "}")). matcher(out). replaceAll(args.get(arg).toString()); } return out; } 如果无法选择 Java 7,您也可以尝试 org.apache.commons.lang3.text.StrSubstitutor。它完全做你想要它做的事。它是否轻量级可能取决于您是否也使用其他 commons-lang 的东西。 Matcher#appendReplacement()会有所帮助 我最近发现JUEL非常符合描述。它是从JSP中取出的表达语言。它声称也非常快。 我即将在我自己的一个项目中尝试一下。 但是对于更轻量级的,这是你的变体,请尝试这个(包含在单元测试中): public class TestInterpolation { public static class NamedFormatter { public final static Pattern pattern = Pattern.compile("#\\{(?<key>.*)}"); public static String format(final String format, Map<String, ? extends Object> kvs) { final StringBuffer buffer = new StringBuffer(); final Matcher match = pattern.matcher(format); while (match.find()) { final String key = match.group("key"); final Object value = kvs.get(key); if (value != null) match.appendReplacement(buffer, value.toString()); else if (kvs.containsKey(key)) match.appendReplacement(buffer, "null"); else match.appendReplacement(buffer, ""); } match.appendTail(buffer); return buffer.toString(); } } @Test public void test() { assertEquals("hello world", NamedFormatter.format("hello #{name}", map("name", "world"))); assertEquals("hello null", NamedFormatter.format("hello #{name}", map("name", null))); assertEquals("hello ", NamedFormatter.format("hello #{name}", new HashMap<String, Object>())); } private Map<String, Object> map(final String key, final Object value) { final Map<String, Object> kvs = new HashMap<>(); kvs.put(key, value); return kvs; } } 我会扩展它以添加便捷的方法来快速键值对 format(format, key1, value1) format(format, key1, value1, key2, value2) format(format, key1, value1, key2, value2, key3, value3) ... 从 java 7+ 转换到 java 6- 应该不会太难 StringTemplate 可能是您可能得到的轻量级插值引擎,尽管我不知道它如何在资源方面与 FreeMarker、Mustache 或 Velocity 之类的东西相比。 另一个选择可能是 EL 引擎,例如 MVEL,它具有 模板引擎。 这是我的解决方案: public class Template { private Pattern pattern; protected Map<CharSequence, String> tokens; private String template; public Template(String template) { pattern = Pattern.compile("\\$\\{\\w+\\}"); tokens = new HashMap<CharSequence, String>(); this.template = template; } public void clearAllTokens() { tokens.clear(); } public void setToken(String token, String replacement) { if(token == null) { throw new NullPointerException("Token can't be null"); } if(replacement == null) { throw new NullPointerException("Replacement string can't be null"); } tokens.put(token, Matcher.quoteReplacement(replacement)); } public String getText() { final Matcher matcher = pattern.matcher(template); final StringBuffer sb = new StringBuffer(); while(matcher.find()) { final String entry = matcher.group(); final CharSequence key = entry.subSequence(2, entry.length() - 1); if(tokens.containsKey(key)) { matcher.appendReplacement(sb, tokens.get(key)); } } matcher.appendTail(sb); return sb.toString(); } public static void main(String[] args) { Template template = new Template("Hello, ${name}."); template.setToken("name", "Eldar"); System.out.println(template.getText()); } } 我知道我的答案来得有点晚了,但如果你仍然需要这个功能,而不需要下载成熟的模板引擎,你可以看看aleph-formatter(我是作者之一): Student student = new Student("Andrei", 30, "Male"); String studStr = template("#{id}\tName: #{st.getName}, Age: #{st.getAge}, Gender: #{st.getGender}") .arg("id", 10) .arg("st", student) .format(); System.out.println(studStr); 或者你可以链接参数: String result = template("#{x} + #{y} = #{z}") .args("x", 5, "y", 10, "z", 15) .format(); System.out.println(result); // Output: "5 + 10 = 15" 在内部,它使用 StringBuilder 通过“解析”表达式创建结果,不执行字符串连接、正则表达式/替换。 我还在我的 str utils 中做了一个(未测试)string.MapFormat("abcd {var}",map)。 //util public static String mapFormat(String template, HashMap<String, String> mapSet) { String res = template; for (String key : mapSet.keySet()) { res = template.replace(String.format("{%s}", key), mapSet.get(key)); } return res; } //use public static void main(String[] args) { boolean isOn=false; HashMap<String, String> kvMap=new HashMap<String, String>(); kvMap.put("isOn", isOn+""); String exp=StringUtils.mapFormat("http://localhost/api/go?isOn={isOn}", kvMap); System.out.println(exp); } 您可以使用Java的字符串模板功能。 它在 JEP 430 中进行了描述,并作为预览功能出现在 JDK 21 中。这是一个使用示例: String name = "Joan"; String info = STR."My name is \{name}"; assert info.equals("My name is Joan"); // true Java 的字符串模板比其他语言(例如 Python 的 f 字符串)中的插值更通用,也更安全。例如,字符串连接或插值使得 SQL 注入攻击成为可能: String query = "SELECT * FROM Person p WHERE p.last_name = '" + name + "'"; ResultSet rs = conn.createStatement().executeQuery(query); 但是这个变体(来自 JEP 430)可以防止 SQL 注入: PreparedStatement ps = DB."SELECT * FROM Person p WHERE p.last_name = \{name}"; ResultSet rs = ps.executeQuery();
假设我有一个 double = 99.00;。如何定义一个字符串格式,在使用 double.ToString(format); 时输出像“0.099”这样的字符串。正如你所看到的,我想格式化我的双...
我有一系列文本块,其中包含写为“2021 年 9 月第一个星期三”或“2022 年 7 月第三个星期一”等的日期。我不确定最好的方法
我现在正在使用java编写一个MUD(基于文本的游戏)。 MUD 的主要方面之一是格式化字符串并将其发送回用户。如何最好地实现这一点? 说我...
我有一些包含零个或多个小数位的浮点数。我想以不超过两位小数的形式显示它们,并且没有尾随零。换句话说,我正在寻找一个
重组 txt 文件 - 识别日期字符串,重新定位并插入字符串
我有一个格式如下的输入 txt 文件: 27/04/2023 00:00 0.1 06:00 0.5 23:00 0.9 28/04/2023 00:00 0.1 06:00 0.5 23:00 0.9 29/04/2023 00:00 0.1 06:00 0.5 23:00 0.9 输出应该看起来...
什么代码或伪代码模拟了 python 的 `str.format` 方法的行为?
为了更好地理解文档,我开始用python风格的伪代码编写str.format。 然而,这是不正确的。 类 str: def 格式(自我,*args,**kwargs): #做
给定一个整数字典,我试图用每个数字和项目的复数形式格式化一个字符串。 示例输入字典: 数据 = {'树':1,'灌木':2,'花':3,'仙人掌':0} 抽样...
如果结果有小数,我如何打印出浮点数,如果结果没有小数,我如何打印出整数? c = input("请输入采购总成本:") bank = raw_input("请输入您的银行...
我在 Java 中有一个字符串,其中包含特殊字符,例如 并且被解释为控制字符并在显示时生成新行和制表符。我想展示这些特别的
将两个列表之间的数据排序到一个新列表中,并使用保存在新列表中的数据格式化字符串列表
抱歉,如果这不是很清楚,这是我第一次在这里提问,所以我希望我能正确解释我的问题。 我有以下具有不同值的列表: A_list = ['A', 'A', ...
将电话号码格式化为“+79998887766”到“+79*********66”并更改字符串颜色android kotlin
我在资源中有这一行: Otp 于 %1$s 发送 作为输入,我得到一个格式为 +79998887766 的字符串(电话号码),我需要插入这个
我有一个 customtkinter 按钮,看起来像这样。 有没有办法可以格式化此按钮文本的部分内容?例如,我希望第一行(“Decline Dumbell Press”)加粗,并且...
设置日志记录的格式样式 - 新样式、旧样式、百分比、括号或 f 字符串)[关闭]
Python 有多种参数字符串格式样式。 旧式/百分比/%: "第一个数字是 %s" % (1,) 新样式/括号/{: “第一个数字是 {}”.format(1) F-
{0[Jack]:d} in Python .format(),这里的'0'表示什么?
table = {'Sjoerd':4127,'Jack':4098,'Dcab':8637678} print('Jack: {[Jack]:d}'.format(table)) 打印('杰克:{0 [杰克]:d} {0 [杰克]:d}'。格式(表)) #print('Jack: {[Jack]:d} {[Jack]:d}'.format...
我有以下字符串作为示例: var str = "3,000, 2000, 1,000" 我想使用正则表达式 str.match(/\d+/g) 提取 3000、2000、1000,但结果是错误的: ['3', '000', '2000...
以下代码引发 KeyError 异常: addr_list_formatted = [] 地址列表 IDX = 0 for addr in addr_list: # addr_list 是一个列表 addr_list_idx = addr_list_idx + 1 addr_list_formatted.
我想知道在 DolphinDB 中是否有 Python rjust 或 zfill 的替代品。 我想在字符串的指定一侧添加 zeros(0),直到它达到指定的长度。我该怎么办?