英文:
Parse user-defined format in Java
问题
我正在用Java编写一个格式解析器,遇到了一些问题。
该格式被存储,以便用户可以根据他们的喜好进行更改。
format: '[prefix] [name] [suffix]: [msg]'
为了将我的值放入格式中,我在Java中使用String.replace()
。
format = getFormatTemplate(); // '[prefix] [name] [suffix]: [msg]';
format = format.replace("[prefix]", prefix); // prefix = "Hello";
format = format.replace("[name]", name); // name = "username";
format = format.replace("[suffix]", suffix); // suffix = "World";
format = format.replace("[msg]", msg); // msg = "Test message";
这将产生预期的输出Hello username World: Test message
。
但是,当字符串的某些部分为空时,那里会有一个空格。
例如,当suffix
为空时,输出将为Hello username : Test message
,请注意名称和冒号之间的空格。
如何在不破坏用户定义的格式的情况下处理这个问题,使得某些部分可以为空?
在解析和应用格式方面是否有更好的方法?
英文:
I am working on a format parser in Java and have some trouble with that.
The format is stored so that users can change it to their likings.
format: '[prefix] [name] [suffix]: [msg]'
To put my values in the format I use String.replace()
in Java.
format = getFormatTemplate(); // '[prefix] [name] [suffix]: [msg]'
format = format.replace("[prefix]", prefix); // prefix = "Hello";
format = format.replace("[name]", name); // name = "username";
format = format.replace("[suffix]", suffix); // suffix = "World";
format = format.replace("[msg]", msg); // msg = "Test message";
This will result in the output Hello username World: Test message
as I expect.
But when some parts of the string are empty there will be a space there.
When for example the suffix
is empty the output will be Hello username : Test message
note the space between the name and the :
How can I get rid of that so that some parts can be empty without breaking the user defined format?
Is there a better way to parse and apply the format?
答案1
得分: 1
以下是翻译好的部分:
静态方法将完成任务:
```lang-java
static String replace(String text, Map<String, String> values) {
StringBuilder result = new StringBuilder();
int textIdx = 0;
for (int startIdx; (startIdx = text.indexOf('[', textIdx)) != -1; ) {
int endIdx = text.indexOf(']', startIdx + 1);
if (endIdx == -1)
break;
result.append(text.substring(textIdx, startIdx));
textIdx = endIdx + 1;
String value = values.get(text.substring(startIdx + 1, endIdx));
if (value != null && !value.isEmpty()) {
result.append(value); // 用非空值替换占位符
} else if (result.length() != 0 && result.charAt(result.length() - 1) == ' ') {
result.setLength(result.length() - 1); // 移除占位符前的空格
} else if (textIdx < text.length() && text.charAt(textIdx) == ' ') {
textIdx++; // 跳过占位符后的空格
}
}
result.append(text.substring(textIdx));
return result.toString();
}
测试
public static void main(String[] args) {
test("[prefix] [name] [suffix]: [msg]",
Map.of("prefix", "Hello",
"name", "username",
"suffix", "World",
"msg", "Test message"));
test("[prefix] [name] [suffix]: [msg]",
Map.of("name", "username",
"suffix", "World",
"msg", "Test message"));
test("[prefix] [name] [suffix]: [msg]",
Map.of("prefix", "Hello",
"suffix", "World",
"msg", "Test message"));
test("[prefix] [name] [suffix]: [msg]",
Map.of("prefix", "Hello",
"name", "username",
"msg", "Test message"));
test("[prefix] [name] [suffix]: [msg]",
Map.of("prefix", "Hello",
"name", "username",
"suffix", "World"));
test("[prefix] [name] [suffix]: [msg]",
Map.of());
}
static void test(String text, Map<String, String> values) {
System.out.println('"' + replace(text, values) + '"');
}
输出
"Hello username World: Test message"
"username World: Test message"
"Hello World: Test message"
"Hello username: Test message"
"Hello username World:"
":"
注意,当连续的占位符缺失或为空时,多个空格被正确消除。
<details>
<summary>英文:</summary>
The following method will do the job:
```lang-java
static String replace(String text, Map<String, String> values) {
StringBuilder result = new StringBuilder();
int textIdx = 0;
for (int startIdx; (startIdx = text.indexOf('[', textIdx)) != -1; ) {
int endIdx = text.indexOf(']', startIdx + 1);
if (endIdx == -1)
break;
result.append(text.substring(textIdx, startIdx));
textIdx = endIdx + 1;
String value = values.get(text.substring(startIdx + 1, endIdx));
if (value != null && ! value.isEmpty()) {
result.append(value); // Replace placeholder with non-empty value
} else if (result.length() != 0 && result.charAt(result.length() - 1) == ' ') {
result.setLength(result.length() - 1); // Remove space before placeholder
} else if (textIdx < text.length() && text.charAt(textIdx) == ' ') {
textIdx++; // Skip space after placeholder
}
}
result.append(text.substring(textIdx));
return result.toString();
}
Test
public static void main(String[] args) {
test("[prefix] [name] [suffix]: [msg]",
Map.of("prefix", "Hello",
"name", "username",
"suffix", "World",
"msg", "Test message"));
test("[prefix] [name] [suffix]: [msg]",
Map.of("name", "username",
"suffix", "World",
"msg", "Test message"));
test("[prefix] [name] [suffix]: [msg]",
Map.of("prefix", "Hello",
"suffix", "World",
"msg", "Test message"));
test("[prefix] [name] [suffix]: [msg]",
Map.of("prefix", "Hello",
"name", "username",
"msg", "Test message"));
test("[prefix] [name] [suffix]: [msg]",
Map.of("prefix", "Hello",
"name", "username",
"suffix", "World"));
test("[prefix] [name] [suffix]: [msg]",
Map.of());
}
static void test(String text, Map<String, String> values) {
System.out.println('"' + replace(text, values) + '"');
}
Output
"Hello username World: Test message"
"username World: Test message"
"Hello World: Test message"
"Hello username: Test message"
"Hello username World:"
":"
Notice how multiple spaces are correctly eliminated when consecutive placeholders are missing/empty.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论