Java:如何根据提供的模式从字符串中提取值并将其填充到映射中?
我有两个字符串,一个是包含参数的模式,另一个是标题 我想从标题中提取参数值,并根据提供的模式将它们存储到映射中。模式中的参数以$作为前缀 例1:Java:如何根据提供的模式从字符串中提取值并将其填充到映射中?,java,algorithm,Java,Algorithm,我有两个字符串,一个是包含参数的模式,另一个是标题 我想从标题中提取参数值,并根据提供的模式将它们存储到映射中。模式中的参数以$作为前缀 例1: pattern = "home/$service/$source-$metadataId" title = "home/serviceA/test-ABC" 然后,输出应该是具有以下所有键值对的映射: service = serviceA source = test metadataId = ABC service = serviceA sourc
pattern = "home/$service/$source-$metadataId"
title = "home/serviceA/test-ABC"
然后,输出应该是具有以下所有键值对的映射:
service = serviceA
source = test
metadataId = ABC
service = serviceA
source = test
region = NA
year = 2019
month = 3
day = 3
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
metadataId = ABC
service = serviceA
source = test
region = NA
year = 2019
month = 3
day = 3
metadataId = ABC
请让我知道是否有任何库可以在Java中实现这一点,或者您将如何在普通Java中实现这一点
注:
String[]p=pattern.split(“/\\$\”);
字符串[]t=标题拆分(“/|-”);
Map Map=newhashmap();
对于(int i=1;i
使用类似于\$(\w+)
的正则表达式将模式拆分为文本块和占位符名称。对于第一个示例,您将获得以下文本块:“home/”
,“/”
,“-”
,”
(最后一个块是空字符串),以及以下占位符名称:“service”
,“源代码”
,“元数据ID”
现在,您可以从如下文本块构造正则表达式:home/(.*)/(.*)-(.*)
。不要忘记正确引用文本块
应用此正则表达式并获取捕获组的值:“serviceA”
,“test”
,“ABC”
将在步骤1中收集的地图占位符名称与在步骤3中获得的捕获组值合并为地图占位符名称
假设参数值(不仅仅是名称)只能包含单词字符,则可以执行以下操作:
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);
}
我基本上转换了你的“模式”在一个带有命名组的正则表达式中。然后,我获取所有组名并使用它们获取捕获的值。最后,我将所有这些放在一个映射中。据我所知,没有库。这个问题非常特定于某些情况。但是,您可以编写自己的库来处理更多类似的情况。下面是一个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();
}
String pattern=“home/$service/aaa/$source-$metadataId”;
字符串title=“home/serviceA/aaa/testabc”;
String patternNew=pattern.replaceAll(“/\\$”-\\$”,“/”;
//假设两个字符串包含相同数量的令牌。
字符串[]keyTokens=(patternNew).split(“/|-”);
字符串[]valueTokens=(title).split(“/|-”);
Map Map=newhashmap();
for(int n=1;n
导入java.util.*;
导入java.io.*;
公共类解决方案{
公共静态void main(字符串[]args)引发IOException{
BufferedReader br=新的BufferedReader(新的InputStreamReader(System.in));
字符串模式=br.readLine();
字符串标题=br.readLine();
System.out.println(parseString(pattern,title.toString());
}
私有静态映射解析字符串(字符串模式、字符串标题){
Map Map=newhashmap();
String[]pat_tokens=pattern.split(“/”);
String[]title_tokens=title.split(“/”);;
对于(int i=0;我不知道有哪一个库可以解析这样的信息。可能您必须手动解析。最好放弃第一个关于推荐库的请求。这些问题在这里完全脱离主题。我也不知道这个问题的现有解决方案。对于“如何解决”这个问题,这取决于您的“模式”的真实性质。意思:有两个例子很好,但您可能需要一个解析器和一个引擎,该引擎接受您的“模式”并将其应用于文本输入。您最好从明确定义这些模式的确切性质开始。因此,通过“不包含任何特殊字符”你的意思是参数名称只包含ASCII字母和数字?我们只看到你的要求,你的尝试也会很好(代码片段)。有没有答案回答你的问题?如果是这样,请考虑接受答案。我认为,这相当接近正确,对于“普通java”。我认为,尽管你必须跳过。“home”字符串,这意味着检查您的参数是否以“$”开头,OP的要求中提到了这一点。它不能处理这种情况:pattern=“home/$service/aaa/$source-$metadataId”和title=“home/serviceA/aaa/test ABC”,因为在这个输入中,模式aaa不是以$开头的。在您所述的问题中(2.所有参数名称都以$开头)。根据您的语句,它应该是$aaa或其他名称。aaa不是一个参数,这与home相同。它只是参数之间的一个常规字符串文字。您希望它通过跳过它来处理“aaa”并跳过“aaa”“值中是否也包含字符串?我明白了。这在您的问题中有点不清楚。我更新了代码。现在应该可以工作了。除非有其他不明确的情况。无论如何,我建议可能为问题添加更多详细信息(更多示例)。这可能是未来读者感兴趣的用例。希望有帮助:)我用修复程序更新了代码。如果您不喜欢密钥名中的$
,您可以使用substring()将其删除。
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;
}
}