在 java 中使用 Regex 格式化字符串,如何将捕获的组转换为特殊字符?
Formatting string with Regex in java, how do I convert captured group to special character?
我有一组包含隐藏字符的命令,写在一个文本文件中。他们一个接一个地被读取并发送给服务器来执行命令。
正确格式化特殊字符非常重要,但是它们不能简单地在文本文件中写成 "\u0002"
,例如,因为那样会被解释为 "\u0002"
,而不是<STX>
个我要找的角色。
因此,我所做的是以这种格式将它们写入文本文件:
$'\x02'test$'\x03'
并且我在 java 中编写了一个正则表达式来提取数值,如下所示:
"\$'\\x(\w\w)'".
(注意额外的转义字符,转义 $
和 \
)
我的问题是:如何获取十六进制字符 (\w\w
),然后将它们转换为字符串中的 Unicode 字符,最好使用 String.format?
我知道我可以使用 ""
物理抓取字符,因为 "(\w\w)"
是每个正则表达式模式中的第一个也是唯一一个组。但是,我在转换时遇到问题。我尝试了以下方法:
String.replaceAll("\$'\\x(\w\w)'",
Character.toString((char)Integer.parseInt("")));
但是 Integer.parseInt("")
部分有问题,因为 </code> 被解释为字符串 <code>""
,而不是捕获的组(例如 02)。
作为一种快速解决方法,我已经为我需要的每个案例实施了一种解决方法,该方法有效。 (例如:String.replace("\$'\\x(02)'", Character.toString((char) (int)0x0002))
)。然而,这显然是一种糟糕的形式,并且对于解析任何情况都没有任何效果。
如果有人可以帮助我并向我指出文档/解释为什么 </code> 被解释为 <code>""
而不是被捕获的组,以及 solution/workaround,将不胜感激。
编辑:
感谢下方的 nhahtdh。他的回答是正确的,虽然我做了一个小修改:
static String handleEscape(String input) {
Pattern p = Pattern.compile("\$'\\x(\w\w)'");
Matcher m = p.matcher(input);
StringBuffer result = new StringBuffer();
while (m.find()) {
m.appendReplacement(result, Character.toString((char) Integer.valueOf(m.group(1), 16)));
}
m.appendTail(result);
return result.toString();
}
我将 Integer.parseInt(m.group(1))
更改为 Integer.valueOf(m.group(1), 16)
,以正确地将任何正确的字符串转换为关联的十六进制值。
由于替换前需要对匹配的文本进行操作,所以需要使用Matcher
中的低级API class手动进行匹配替换
static String handleEscape(String input) {
Pattern p = Pattern.compile("\$'\\x(\w\w)'");
Matcher m = p.matcher(input);
StringBuffer result = new StringBuffer();
while (m.find()) {
m.appendReplacement(result,
Character.toString((char) Integer.parseInt(m.group(1), 16)));
}
m.appendTail(result);
return result.toString();
}
我有一组包含隐藏字符的命令,写在一个文本文件中。他们一个接一个地被读取并发送给服务器来执行命令。
正确格式化特殊字符非常重要,但是它们不能简单地在文本文件中写成 "\u0002"
,例如,因为那样会被解释为 "\u0002"
,而不是<STX>
个我要找的角色。
因此,我所做的是以这种格式将它们写入文本文件:
$'\x02'test$'\x03'
并且我在 java 中编写了一个正则表达式来提取数值,如下所示:
"\$'\\x(\w\w)'".
(注意额外的转义字符,转义 $
和 \
)
我的问题是:如何获取十六进制字符 (\w\w
),然后将它们转换为字符串中的 Unicode 字符,最好使用 String.format?
我知道我可以使用 ""
物理抓取字符,因为 "(\w\w)"
是每个正则表达式模式中的第一个也是唯一一个组。但是,我在转换时遇到问题。我尝试了以下方法:
String.replaceAll("\$'\\x(\w\w)'",
Character.toString((char)Integer.parseInt("")));
但是 Integer.parseInt("")
部分有问题,因为 </code> 被解释为字符串 <code>""
,而不是捕获的组(例如 02)。
作为一种快速解决方法,我已经为我需要的每个案例实施了一种解决方法,该方法有效。 (例如:String.replace("\$'\\x(02)'", Character.toString((char) (int)0x0002))
)。然而,这显然是一种糟糕的形式,并且对于解析任何情况都没有任何效果。
如果有人可以帮助我并向我指出文档/解释为什么 </code> 被解释为 <code>""
而不是被捕获的组,以及 solution/workaround,将不胜感激。
编辑:
感谢下方的 nhahtdh。他的回答是正确的,虽然我做了一个小修改:
static String handleEscape(String input) {
Pattern p = Pattern.compile("\$'\\x(\w\w)'");
Matcher m = p.matcher(input);
StringBuffer result = new StringBuffer();
while (m.find()) {
m.appendReplacement(result, Character.toString((char) Integer.valueOf(m.group(1), 16)));
}
m.appendTail(result);
return result.toString();
}
我将 Integer.parseInt(m.group(1))
更改为 Integer.valueOf(m.group(1), 16)
,以正确地将任何正确的字符串转换为关联的十六进制值。
由于替换前需要对匹配的文本进行操作,所以需要使用Matcher
中的低级API class手动进行匹配替换
static String handleEscape(String input) {
Pattern p = Pattern.compile("\$'\\x(\w\w)'");
Matcher m = p.matcher(input);
StringBuffer result = new StringBuffer();
while (m.find()) {
m.appendReplacement(result,
Character.toString((char) Integer.parseInt(m.group(1), 16)));
}
m.appendTail(result);
return result.toString();
}