解析 Java 中的用户定义格式

huangapple go评论109阅读模式
英文:

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&lt;String, String&gt; values) {
	StringBuilder result = new StringBuilder();
	int textIdx = 0;
	for (int startIdx; (startIdx = text.indexOf(&#39;[&#39;, textIdx)) != -1; ) {
		int endIdx = text.indexOf(&#39;]&#39;, 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 &amp;&amp; ! value.isEmpty()) {
			result.append(value); // Replace placeholder with non-empty value
		} else if (result.length() != 0 &amp;&amp; result.charAt(result.length() - 1) == &#39; &#39;) {
			result.setLength(result.length() - 1); // Remove space before placeholder
		} else if (textIdx &lt; text.length() &amp;&amp; text.charAt(textIdx) == &#39; &#39;) {
			textIdx++; // Skip space after placeholder
		}
	}
	result.append(text.substring(textIdx));
	return result.toString();
}

Test

public static void main(String[] args) {
	test(&quot;[prefix] [name] [suffix]: [msg]&quot;,
	     Map.of(&quot;prefix&quot;, &quot;Hello&quot;,
	            &quot;name&quot;, &quot;username&quot;,
	            &quot;suffix&quot;, &quot;World&quot;,
	            &quot;msg&quot;, &quot;Test message&quot;));
	test(&quot;[prefix] [name] [suffix]: [msg]&quot;,
	     Map.of(&quot;name&quot;, &quot;username&quot;,
	            &quot;suffix&quot;, &quot;World&quot;,
	            &quot;msg&quot;, &quot;Test message&quot;));
	test(&quot;[prefix] [name] [suffix]: [msg]&quot;,
	     Map.of(&quot;prefix&quot;, &quot;Hello&quot;,
	            &quot;suffix&quot;, &quot;World&quot;,
	            &quot;msg&quot;, &quot;Test message&quot;));
	test(&quot;[prefix] [name] [suffix]: [msg]&quot;,
	     Map.of(&quot;prefix&quot;, &quot;Hello&quot;,
	            &quot;name&quot;, &quot;username&quot;,
	            &quot;msg&quot;, &quot;Test message&quot;));
	test(&quot;[prefix] [name] [suffix]: [msg]&quot;,
	     Map.of(&quot;prefix&quot;, &quot;Hello&quot;,
	            &quot;name&quot;, &quot;username&quot;,
	            &quot;suffix&quot;, &quot;World&quot;));
	test(&quot;[prefix] [name] [suffix]: [msg]&quot;,
	     Map.of());
}

static void test(String text, Map&lt;String, String&gt; values) {
	System.out.println(&#39;&quot;&#39; + replace(text, values) + &#39;&quot;&#39;);
}

Output

&quot;Hello username World: Test message&quot;
&quot;username World: Test message&quot;
&quot;Hello World: Test message&quot;
&quot;Hello username: Test message&quot;
&quot;Hello username World:&quot;
&quot;:&quot;

Notice how multiple spaces are correctly eliminated when consecutive placeholders are missing/empty.

huangapple
  • 本文由 发表于 2020年6月29日 03:47:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/62627487.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定