我有一个Java字符串,格式如下。
String s = "City: [name:NYK][distance:1100] [name:CLT][distance:2300] [name:KTY][distance:3540] Price:"
使用java.util.regex包的matcher和pattern类,我必须以以下格式获取输出字符串:
Output: [NYK:1100][CLT:2300][KTY:3540]
你能提供一个正则表达式模式,帮助我得到上述的输出格式吗?
我有一个Java字符串,格式如下。
String s = "City: [name:NYK][distance:1100] [name:CLT][distance:2300] [name:KTY][distance:3540] Price:"
Output: [NYK:1100][CLT:2300][KTY:3540]
你可以像这样使用正则表达式\[name:([A-Z]+)\]\[distance:(\d+)\]
:
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("]");
}
name:(?<name>[A-Z]+)
,然后作为 matcher.group("name")
访问。这样,在访问点清楚地知道你要访问的片段,更易理解。 - Tim M.name:(?<name>[A-Z]+)
的好方法 @tradeJmark,然后可以通过 matcher.group("name")
访问。老实说,这是我第一次看到它,我已经测试过它,它非常有效。String regex = "\\[name:(?<name>[A-Z]+)\\]\\[distance:(?<distance>\\d+)\\]";
如果您不介意,我会将其添加到我的答案中 :) - Youcef LAIDANI如果字符串的格式是固定的,而且你总是只有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]
块模式匹配:
\\s*
- 0个或多个空格\\[name:
- 匹配字面值字符串 [name:
([A-Z]+)
- 匹配并捕获一个或多个大写 ASCII 字符(也可以使用 \\w+
) ]\\[distance:
- 匹配字面值字符串 ][distance:
(\\d+)
- 匹配并捕获一个或多个数字]
- 匹配 ]
符号。在模式.*%1$s%1$s%1$s.*
中,组将具有1到6个ID(使用替换模式的$1
- $6
反向引用来引用它们),而首尾的.*
将删除字符串的开头和结尾(如果字符串可能包含换行符,请在模式开头添加(?s)
)。