用Java替换多个字符为其他多个字符。

huangapple 未分类评论46阅读模式
英文:

Replacing multiple characters in Java with other multiple characters?

问题

我看到有一些类似的问题,但那里的答案对我没有真正帮助。
无论如何,我有一个像这样的字符串:"Today is Saturday"。我需要将每个字符'a'更改为'b',每个字符'o'更改为'f'。基本上是用多个字符替换多个字符。现在,我尝试过像这样做:

String string.replace("a","b").replace("o","f");

但它只执行第一次替换。我尝试过使用StringBuilder:

stringBuilder.append(string);
for (int i=0; i<stringBuilder.length(); i++){
    char c=stringBuilder.charAt(i);
    if (c=='a'){
        我不知道如何在这里替换为'b'...
    }
}

stringBuilder.toString();

我读到可以使用映射(maps),但我以前从未使用过,也不知道如何做。有谁可以帮助我解决这个问题吗?

英文:

I've seen that there's some similar questions to this one, but answers there didn't really help me.
Anyways, I have a string like this "Today is Saturday". I need to change every char 'a' to 'b' and every char 'o' to 'f'. Basically, replacing multiple characters with multiple characters. Now, I've tried doing something like this:

String string.replace(&quot;a&quot;,&quot;b&quot;).replace(&quot;o&quot;,&quot;f&quot;);

But it only does the first replacement. I've tried using Stringbuilder:

stringBuilder.append(string);
for (int i=0; i&lt;stringBuilder.length(); i++){
    char c=stringBuilder.charAt(i);
    if (c==&#39;a&#39;){
        I don&#39;t know how to replace it here to &#39;b&#39;...
    }
}

stringBuilder.toString();

I've read I could use maps but I've never used them before and don't know how to do it. Can anyone please help me out with this?

答案1

得分: 0

像您想要的是类似于 SQL 的 `TRANSLATE` 函数的方法。

```lang-java
public static String translate(String input, String fromChars, String toChars) {
	if (fromChars.isEmpty() || fromChars.length() != toChars.length())
		throw new IllegalArgumentException();
	if (input == null || input.isEmpty())
		return input;
	char[] buf = input.toCharArray();
	for (int i = 0; i < buf.length; i++) {
		char ch = buf[i];
		for (int j = 0; j < fromChars.length(); j++) {
			if (fromChars.charAt(j) == ch) {
				buf[i] = toChars.charAt(j);
				break;
			}
		}
	}
	return new String(buf);
}

测试

System.out.println(translate("Today is Saturday", "ao", "bf"));

输出

Tfdby is Sbturdby

这是一个使用 Map 的版本,它支持来自补充平面的 Unicode 字符,例如表情符号:

public static String translate(String input, String fromChars, String toChars) {
	// 构建码点映射表
	if (fromChars.isEmpty() || fromChars.length() < toChars.length()) {
		throw new IllegalArgumentException("fromChars 不能比 toChars 短 (" +
				fromChars.length() + " < " + toChars.length() + ")");
	}
	Map<Integer, String> map = new HashMap<>();
	for (int fromIdx = 0, fromEnd, toIdx = 0; fromIdx < fromChars.length(); fromIdx = fromEnd) {
		fromEnd = fromChars.offsetByCodePoints(fromIdx, 1);
		String mapped = "";
		if (toIdx < toChars.length()) {
			int toEnd = toChars.offsetByCodePoints(toIdx, 1);
			mapped = toChars.substring(toIdx, toEnd);
			toIdx = toEnd;
		}
		if (map.put(fromChars.codePointAt(fromIdx), mapped) != null) {
			throw new IllegalArgumentException("fromChars 中索引 " + fromIdx + " 处有重复值: " +
			                                   fromChars.substring(fromIdx, fromEnd));
		}
	}
	
	// 映射码点
	if (input == null || input.isEmpty())
		return input;
	StringBuilder buf = new StringBuilder();
	for (int idx = 0, end; idx < input.length(); idx = end) {
		end = input.offsetByCodePoints(idx, 1);
		String mapped = map.get(input.codePointAt(idx));
		buf.append(mapped != null ? mapped : input.substring(idx, end));
	}
	return buf.toString();
}

测试

System.out.println(translate("Today is Saturday &#128512;", "ao&#128512;r", "bf&#128533;"));

输出

Tfdby is Sbtudby &#128533;

请注意,由于 toChars 较短,r 被删除了。这就是 SQL 的 TRANSLATE 函数的工作方式。


<details>
<summary>英文:</summary>

Sounds like you want a method similar to the SQL `TRANSLATE` function.

```lang-java
public static String translate(String input, String fromChars, String toChars) {
	if (fromChars.isEmpty() || fromChars.length() != toChars.length())
		throw new IllegalArgumentException();
	if (input == null || input.isEmpty())
		return input;
	char[] buf = input.toCharArray();
	for (int i = 0; i &lt; buf.length; i++) {
		char ch = buf[i];
		for (int j = 0; j &lt; fromChars.length(); j++) {
			if (fromChars.charAt(j) == ch) {
				buf[i] = toChars.charAt(j);
				break;
			}
		}
	}
	return new String(buf);
}

Test

System.out.println(translate(&quot;Today is Saturday&quot;, &quot;ao&quot;, &quot;bf&quot;));

Output

Tfdby is Sbturdby

Here is a version using Map, which supports Unicode characters from the Supplemental Planes, e.g. Emojis:

public static String translate(String input, String fromChars, String toChars) {
	// Build codepoint mapping table
	if (fromChars.isEmpty() || fromChars.length() &lt; toChars.length()) {
		throw new IllegalArgumentException(&quot;fromChars cannot be shorter than toChars (&quot; +
				fromChars.length() + &quot; &lt; &quot; + toChars.length() + &quot;)&quot;);
	}
	Map&lt;Integer, String&gt; map = new HashMap&lt;&gt;();
	for (int fromIdx = 0, fromEnd, toIdx = 0; fromIdx &lt; fromChars.length(); fromIdx = fromEnd) {
		fromEnd = fromChars.offsetByCodePoints(fromIdx, 1);
		String mapped = &quot;&quot;;
		if (toIdx &lt; toChars.length()) {
			int toEnd = toChars.offsetByCodePoints(toIdx, 1);
			mapped = toChars.substring(toIdx, toEnd);
			toIdx = toEnd;
		}
		if (map.put(fromChars.codePointAt(fromIdx), mapped) != null) {
			throw new IllegalArgumentException(&quot;Duplicate value in fromChars at index &quot; + fromIdx + &quot;: &quot; +
			                                   fromChars.substring(fromIdx, fromEnd));
		}
	}
	
	// Map codepoints
	if (input == null || input.isEmpty())
		return input;
	StringBuilder buf = new StringBuilder();
	for (int idx = 0, end; idx &lt; input.length(); idx = end) {
		end = input.offsetByCodePoints(idx, 1);
		String mapped = map.get(input.codePointAt(idx));
		buf.append(mapped != null ? mapped : input.substring(idx, end));
	}
	return buf.toString();
}

Test

System.out.println(translate(&quot;Today is Saturday &#128512;&quot;, &quot;ao&#128512;r&quot;, &quot;bf&#128533;&quot;));

Output

Tfdby is Sbtudby &#128533;

Notice how the r is removed, because toChars is shorter than fromChars. This is how the SQL TRANSLATE function works.

huangapple
  • 本文由 发表于 2020年5月2日 18:14:32
  • 转载请务必保留本文链接:https://java.coder-hub.com/61557671.html
匿名

发表评论

匿名网友

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

确定