我有以下格式的以下java字符串。
String s = "City: [name:NYK][distance:1100] [name:CLT][distance:2300] [name:KTY][distance:3540] Price:"
使用java.util.regex包问题和模式类我必须以下列格式获取输出字符串:
Output: [NYK:1100][CLT:2300][KTY:3540]
你能建议一个可以帮助我获得上述输出格式的RegEx模式吗?
答案 0 :(得分:9)
您可以将此正则表达式\[name:([A-Z]+)\]\[distance:(\d+)\]
与Pattern结合使用:
String regex = "\\[name:([A-Z]+)\\]\\[distance:(\\d+)\\]";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(s);
StringBuilder result = new StringBuilder();
while (matcher.find()) {
result.append("[");
result.append(matcher.group(1));
result.append(":");
result.append(matcher.group(2));
result.append("]");
}
System.out.println(result.toString());
<强>输出强>
[NYK:1100][CLT:2300][KTY:3540]
\[name:([A-Z]+)\]\[distance:(\d+)\]
意味着获得两个组,一个是\[name:([A-Z]+)\]
之后的大写字母,第二个是\[distance:(\d+)\]
之后的数字@tradeJmark的另一个解决方案,您可以使用此正则表达式:
String regex = "\\[name:(?<name>[A-Z]+)\\]\\[distance:(?<distance>\\d+)\\]";
因此,您可以轻松地按组的名称而不是像这样的索引获取每个组的结果:
while (matcher.find()) {
result.append("[");
result.append(matcher.group("name"));
//----------------------------^^
result.append(":");
result.append(matcher.group("distance"));
//------------------------------^^
result.append("]");
}
答案 1 :(得分:3)
如果字符串的格式是固定的,并且您内部只有3个[...]
组来处理,则可以定义与[name:...]
匹配的块并捕获将两部分分成不同的组,并使用一个非常简单的代码.replaceAll
:
String s = "City: [name:NYK][distance:1100] [name:CLT][distance:2300] [name:KTY][distance:3540] Price:";
String matchingBlock = "\\s*\\[name:([A-Z]+)]\\[distance:(\\d+)]";
String res = s.replaceAll(String.format(".*%1$s%1$s%1$s.*", matchingBlock),
"[$1:$2][$3:$4][$5:$6]");
System.out.println(res); // [NYK:1100][CLT:2300][KTY:3540]
请参阅Java demo和regex demo。
块模式匹配:
\\s*
- 0+ whitespaces \\[name:
- 文字[name:
子字符串([A-Z]+)
- 组n捕获1个或多个大写ASCII字符(\\w+
也可以使用)]\\[distance:
- 文字][distance:
子字符串(\\d+)
- 群组m捕获一个或多个数字]
- ]
符号。在.*%1$s%1$s%1$s.*
模式中,这些组将包含1到6个ID(从替换模式引用$1
- $6
反向引用)和前导{{1}将删除字符串的开始和结束(如果字符串可以包含换行符,则在模式的开头添加.*
。)