我有一个格式如下的字符串:
"key1=value1;key2=value2;key3=value3"
任意数量的键/值对。
我需要检查某个键是否存在(假设它叫做“特殊键”)。如果是,我想要与之相关的值。如果有多个“特殊键”设置,我只想要第一个。
现在,我正在寻找“特殊键”的索引。我从该索引处开始一个子字符串,然后查找第一个=
字符的索引。然后我查找第一个;
字符的索引。这两个索引之间的子字符串给出了与“特殊键”相关联的值。
这不是一个优雅的解决方案,它真的很困扰我。找到与“特殊键”对应的值的优雅方法是什么?
答案 0 :(得分:10)
我会将String解析为一个映射,然后检查密钥:
String rawValues = "key1=value1;key2=value2;key3=value3";
Map<String,String> map = new HashMap<String,String>();
String[] entries = rawValues.split(";");
for (String entry : entries) {
String[] keyValue = entry.split("=");
map.put(keyValue[0],keyValue[1]);
}
if (map.containsKey("myKey") {
return map.get("myKey");
}
答案 1 :(得分:8)
使用String.split:
String[] kvPairs = "key1=value1;key2=value2;key3=value3".split(";");
这将为您提供包含以下元素的数组kvPairs
:
key1=value1
key2=value2
key3=value3
迭代这些并将它们分开:
for(String kvPair: kvPairs) {
String[] kv = kvPair.split("=");
String key = kv[0];
String value = kv[1];
// Now do with key whatever you want with key and value...
if(key.equals("specialkey")) {
// Do something with value if the key is "specialvalue"...
}
}
答案 2 :(得分:5)
如果它只是您所关注的一个键,您可以使用正则表达式\bspecialkey=([^;]+)(;|$)
并提取捕获组1:
Pattern p = Pattern.compile("\\bspecialkey=([^;]+)(;|$)");
Matcher m = p.matcher("key1=value1;key2=value2;key3=value3");
if (m.find()) {
System.out.println(m.group(1));
}
如果您正在使用其他键执行某些操作,请在循环中拆分;
然后=
- 不需要正则表达式。
答案 3 :(得分:2)
如果有人对纯正的基于Regex的方法感兴趣,以下代码段可以正常工作。
Pattern pattern = Pattern.compile("([\\w]+)?=([\\w]+)?;?");
Matcher matcher = pattern.matcher("key1=value1;key2=value2;key3=value3");
while (matcher.find()) {
System.out.println("Key - " + matcher.group(1) + " Value - " + matcher.group(2);
}
输出
Key - key1 Value - value1
Key - key2 Value - value2
Key - key3 Value - value3
然而,正如其他人之前所解释的那样,任何一天都建议String.split()
进行此类任务。在没有使用正则表达式的情况下,尝试使用Regex时,您的生活不应该复杂化。
答案 4 :(得分:1)
有很多方法可以做到这一点。也许最简单的方法是使用 Streams API(从 Java 8 及更高版本开始可用)来处理匹配结果:
List<String> OriginalList = Arrays.asList("A=1,B=2,C=3",
"A=11,B=12,C=13,D=15", "A=5,B=4,C=9,D=10,E=13",
"A=19,B=20,C=91,D=40,E=33", "A=77,B=27,C=37");
Pattern p = Pattern.compile("A=(\\d+)");
List<Integer> result = OriginalList.stream().
flatMap(str->p.matcher(str).results())
.map(mr->Integer.valueOf(mr.group(1)))
.collect(Collectors.toList());
System.out.println(result);
打印:
[1, 11, 5, 19, 77]
答案 5 :(得分:1)
这可以使用 Stream API 实现,方法是将输入列表中的每个字符串用逗号和 Stream::flatMap
进行简单拆分
// assuming A is not always at the beginning
List<String> list = Arrays.asList(
"A=1,B=2,C=3",
"A=11,B=12,C=13,D=15",
"A=5,B=4,C=9,D=10,E=13",
"B=20,C=91,D=40,E=33",
"B=27, A=19, C=37, A=77");
List<Integer> aNums = list.stream() // Stream<String>
.flatMap(
s -> Arrays.stream(s.split("\\s*,\\s*")) // Stream<String> pairs of letter=digits
.filter(pair -> pair.startsWith("A="))
.map(pair -> Integer.valueOf(pair.substring(2)))
)
.collect(Collectors.toList());
System.out.println(aNums);
输出:
[1, 11, 5, 19, 77]
更新
可以按如下方式应用拆分输入字符串并仅保留与 A
相关的数字的模式:
Pattern splitByA = Pattern.compile("A\\s*=\\s*|\\s*,\\s*|[^A]\\s*=\\s*\\d+");
List<Integer> aNums2 = list.stream()
.flatMap(splitByA::splitAsStream) // Stream<String>
.filter(Predicate.not(String::isEmpty)) // need to remove empty strings
.map(Integer::valueOf)
.collect(Collectors.toList());
System.out.println(aNums2);
输出相同
[1, 11, 5, 19, 77]
答案 6 :(得分:0)
Regex非常适合同时进行匹配和解析:
//c#
string input = @"key1=value1;specialkey=scott;key3=value3";
var specialkey = Regex.Match(input, "specialkey=(.*?);").Groups[1].Value;
Console.WriteLine(specialkey);
答案 7 :(得分:0)
尝试:(?:(?:A=)([^,]*))
演示:https://regex101.com/r/rziGDz/1
否则你会使用正则表达式和你的列表找到一个代码来获得答案:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.*;
public class Main
{
public static void main(String[] args)
{
List<Integer> results = new ArrayList();
Pattern pattern = Pattern.compile("(?:(?:A=)([^,]*))", Pattern.CASE_INSENSITIVE);
List<String> OriginalList = Arrays.asList(
"A=1,B=2,C=3",
"A=11,B=12,C=13,D=15",
"A=5,B=4,C=9,D=10,E=13",
"A=19,B=20,C=91,D=40,E=33",
"A=77,B=27,C=37");
for (int i = 0; i < OriginalList.size(); i++)
{
Matcher matcher = pattern.matcher(OriginalList.get(i));
boolean matchFound = matcher.find();
if(matchFound)
{
System.out.println( matcher.group(1) );
results.add( Integer.parseInt(matcher.group(1)) );
}
}
}
}
答案 8 :(得分:0)
使用基本过滤器:使用 [A-Z=,]+
正则表达式拆分。选择第二个元素。
public List filter() {
List<String> originalList = Arrays.asList("A=1,B=2,C=3", "A=11,B=12,C=13,D=15", "A=5,B=4,C=9,D=10,E=13",
"A=19,B=20,C=91,D=40,E=33", "A=77,B=27,C=37");
List<Integer> parsedData = new ArrayList();
for(String str: originalList) {
Integer data = Integer.parseInt(str.split("[A-Z=,]+")[1]);
parsedData.add(data);
}
return parsedData;
}
答案 9 :(得分:0)
试试这个:
List<Integer> results = new ArrayList();
Pattern p = Pattern.compile("(?:(?:A=)([^,]*))");
Matcher m = null;
for (String tmp : OriginalList) {
m = p.matcher(tmp);
if (m.find()) {
int r = Integer.parseInt(m.group(0).replace("A=", ""));
results.add(r);
}
}