我有2个字符串,一个是包含参数的模式,另一个是标题。
我想从标题中提取参数值,然后根据提供的模式将其存储到Map中。模式中的参数以$开头。
示例1:
pattern = "home/$service/$source-$metadataId"
title = "home/serviceA/test-ABC"
然后输出应该是具有所有以下键值对的映射:
service = serviceA
source = test
metadataId = ABC
示例2:
pattern = "home/$service/$source/$region/$year/$month/$day-$metadataId"
title = "home/serviceA/test/NA/2019/3/3-ABC"
然后输出应该是具有所有以下键值对的映射:
service = serviceA
source = test
region = NA
year = 2019
month = 3
day = 3
metadataId = ABC
请让我知道是否有任何库可以用Java做到这一点,或者您将如何用普通Java实现它。
注意:
答案 0 :(得分:1)
我不知道任何图书馆。此问题在某些情况下非常具体。但是您可以编写自己的库来处理更多类似情况。这是一个Java小程序,适用于您描述的所有情况(可以进一步扩展)。希望它能给您一些想法。
String pattern = "home/$service/aaa/$source-$metadataId";
String title = "home/serviceA/aaa/test-ABC";
String patternNew = pattern.replaceAll("/\\$|-\\$", "/");
// assuming both the strings contain same number of tokens.
String[] keyTokens = (patternNew).split("/|-");
String[] valueTokens = (title).split("/|-");
Map<String, String> map = new HashMap<String, String>();
for (int n = 1; n < keyTokens.length; n++) {
String key = (keyTokens[n]);
String value = (valueTokens[n]);
if(key.equals(value))
continue;
map.put(key, value);
}
for (String name : map.keySet()) {
System.out.print(name);
System.out.print(" = " + map.get(name));
System.out.println();
}
答案 1 :(得分:0)
String[] p = pattern.split("/\\$|-");
String[] t = titlesplit("/|-");
Map<String, String> map = new HashMap<>();
for(int i=1; i<t.length; i++){
map.put(p[i], t[i]);
}
答案 2 :(得分:0)
\$(\w+)
的正则表达式将模式分为文字块和占位符名称。对于第一个示例,您将获得以下文字块:"home/"
,"/"
,"-"
,""
(最后一块是空字符串),以及以下占位符名称:{ {1}},"service"
,"source"
。"metadataId"
从文字块构造正则表达式。不要忘记正确引用文字块。home/(.*)/(.*)-(.*)
,"serviceA"
,"test"
。答案 3 :(得分:0)
假设参数 values (不仅仅是名称)只能包含文字字符,您可以这样做:
String pattern = "home/$service/$source/$region/$year/$month/$day-$metadataId";
String title = "home/serviceA/test/NA/2019/3/3-ABC";
String regex = "\\Q" + pattern.replaceAll("\\$(\\w+)", "\\\\E(?<$1>\\\\w+)\\\\Q") + "\\E";
Matcher m = Pattern.compile(regex).matcher(title);
if (m.find()) {
Map<String, String> map = getNamedGroupCandidates(regex).stream().collect(Collectors.toMap(Function.identity(), m::group));
System.out.println(map);
}
getNamedGroupCandidates
来自此post的地方:
private static Set<String> getNamedGroupCandidates(String regex) {
Set<String> namedGroups = new TreeSet<>();
Matcher m = Pattern.compile("\\(\\?<([a-zA-Z][a-zA-Z0-9]*)>").matcher(regex);
while (m.find()) {
namedGroups.add(m.group(1));
}
return namedGroups;
}
我基本上将您的“模式”转换为带有命名组的正则表达式。然后,我获取所有组名并使用它们来获取捕获的值。最后,我将所有这些放到一张地图中。
答案 4 :(得分:0)
import java.util.*;
import java.io.*;
public class Solution {
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String pattern = br.readLine();
String title = br.readLine();
System.out.println(parseString(pattern,title).toString());
}
private static Map<String,String> parseString(String pattern,String title){
Map<String,String> map = new HashMap<>();
String[] pat_tokens = pattern.split("/");
String[] title_tokens = title.split("/");;
for(int i=0;i<pat_tokens.length;++i){
String[] sub_tokens = pat_tokens[i].split("\\-");
String[] title_sub_tokens = title_tokens[i].split("\\-");
for(int j=0;j<sub_tokens.length;++j){
if(sub_tokens[j].charAt(0) != '$') continue;
map.put(sub_tokens[j],title_sub_tokens[j]);
}
}
return map;
}
}
好吧,您可以仅基于/
和-
拆分单个令牌的字符串。如果字符串的起始字符不是$
,则它不是您希望将其包含在映射中的键。