我正在努力尋找解決這個問題的方法。我有需要用與原始字符映射的特定字符替換的字串列。
例如:我有保存字符的字符映射,它是替換值。字符映射:
Map<String, String> characterMap = new HashMap<String, String>();
characterMap.put("&", "\x26");
characterMap.put("^", "\x5e");
需要String hello = "Hello& World^";
替換的字串:我想用地圖中的值替換 hello 字串。該地圖是從屬性檔案創建的,它是動態的。
我可以通過正則運算式實作這一點嗎?我可以在不迭代字符映射的情況下實作這一點嗎?
uj5u.com熱心網友回復:
您可以使用以下代碼:
Map<String, String> characterMap = new HashMap<>();
characterMap.put("&", "\\x26");
characterMap.put("^", "\\x5e");
String hello = "Hello& World^";
Pattern.compile("\\W").matcher(hello).replaceAll(
m -> characterMap.getOrDefault(m.group(), m.group())
.replaceAll("\\\\", "$0$0"));
輸出:
"Hello\\x26 World\\x5e"
細節:
- 在主正則運算式中,我們匹配
\\W將匹配任何非單詞 - 我們從中提取每個匹配的非單詞字符的值,
characterMap或者如果找不到該鍵,我們將回傳相同的字符。 - 我們呼叫
.replaceAll("\\\\", "$0$0")提取的值來獲得正確的轉義(假設值只是使用單個轉義)。$0是我們在正則運算式中匹配的完整字串,它是\\\\并且通過使用$0$0我們制作它\\\\\\\\。
Code Demo
另一種優化的方法是使用地圖的鍵構造正則運算式,如下所示:
Pattern p = Pattern.compile(characterMap.keySet().stream()
.map(s -> Pattern.quote(s)).collect(Collectors.joining("|")));
// then use it with . getOrDefault
p.matcher(hello).replaceAll(m ->
characterMap.get(m.group()).replaceAll("\\\\", "$0$0"));
// => "Hello\\x26 World\\x5e"
uj5u.com熱心網友回復:
反斜杠必須轉義,產生兩個反斜杠\\;在 java 字串文字和 .properties 檔案中。
Map<String, String> characterMap = new LinkedHashMap<>(); // Linked = keep order of inserting.
characterMap.put("&", "\\x26");
characterMap.put("^", "\\x5e");
但是你提到源是一個檔案。
ResourceBundle bundle = ResourceBundle.getBundle("charmap");
String hello = "Hello& World^";
System.out.println("Replaced: " mapReplace(hello, bundle));
魅力地圖屬性:
\\ = xx
& = \\x26
^ = \\x5e
為了不被替換,最好替換字符。
private String mapReplace(String s, ResourceBundle characterMap) {
Pattern p = Pattern.compile(".");
Matcher m = p.matcher(s);
return m.replaceAll(mr -> {
String c = mr.group();
if (characterMap.containsKey(c)) {
c = m.quoteReplacement(characterMap.getString(c));
}
return c;
});
}
該Matcher#replaceAll預計更換是在正則運算式的風格,反斜線再次,美元$也和這樣的。為此,可以使用Matcher#quoteReplacement.
最后但并非最不重要的一點是,如果您只想\x..作為替代品:
private String mapReplace(String s, String keys) {
return Pattern.compile("[" keys.replaceAll(".", "\\\\$0") "]").matcher(s)
.replaceAll(mr -> String.format("\\\\xx", (int)mr.group().charAt(0)));
}
hello = mapReplace(hello, "^&");
將keys.replaceAll(".", "\\\\$0")需要有正則運算式[\^\&]又名"[\\^\\&]"為-,^和其他人正則運算式中的特殊含義。
一般來說,建議使用\uXXXX而不是\xXX.
看到這兩個字符,這個任務幾乎看起來像是一個 ASCII 到 EBCDIC 的轉換。那可以做不同的事情。
您還可以使用 URL 編碼&/ ^,其中存在 URLEncoder。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/409291.html
標籤:
上一篇:需要提取句號之前的所有數字及其之前的空格。數字可以是正數或負數
下一篇:如何使用按鈕更新圖表?
