字符串匹配器在java中查找键值

字符串匹配器在java中查找键值,java,string,pattern-matching,Java,String,Pattern Matching,我的要求是我有一个给定的字符串,比如 String originalString=“德里到果阿” 我有一根绳子 String regStr=“%{orgCity}到%{destCity}” 给定的文本可以是任何格式。(不仅仅是“德里到果阿”,还可以是“德里到果阿”) 现在,给定这两个字符串,我想得到一个键值对为 orgCity->德里 目的地城市->果阿 这里key是%{和}之间的字符串。值是原始字符串中对应的字符串 这需要使用一些正则表达式/模式来实现 我找不到解决这个问题的办法 有人能帮忙吗

我的要求是我有一个给定的字符串,比如
String originalString=“德里到果阿”

我有一根绳子
String regStr=“%{orgCity}到%{destCity}”

给定的文本可以是任何格式。(不仅仅是“德里到果阿”,还可以是“德里到果阿”)

现在,给定这两个字符串,我想得到一个键值对为

orgCity->德里

目的地城市->果阿

这里key是%{和}之间的字符串。值是原始字符串中对应的字符串

这需要使用一些正则表达式/模式来实现

我找不到解决这个问题的办法

有人能帮忙吗

谢谢

已更新

解决方案:

public static void main(String[] args) {

    // Original requirement
    System.out.println(getValueMap("%{orgCity} to %{destCity}", "delhi to goa"));

    // A variation with two words values
    System.out.println(getValueMap("%{orgCity} to %{destCity}", "New York to Mexico"));

    // Another variation
    System.out.println(getValueMap("%{orgCity} to %{destCity} and more", "delhi to goa and more"));

    // order of words doesn't matter
    System.out.println(getValueMap("%{orgCity} %{destCity} to", "delhi goa to"));

    // different strings than the original requirement
    System.out.println(getValueMap("I'm going to %{firstCity} and then to %{secondCity}", "I'm going to Nauru and then to Seattle"));

    // more than two values, with more than one word
    System.out.println(getValueMap("I am %{age} years old, I have %{eyesColour} eyes and %{pocketContent} in my pocket",
              "I am 20 years old, I have dark blue eyes and two coins in my pocket"));

    // etc ...
}

public static Map<String, String> getValueMap(String format, String text) {
    Map<String, String> map = new HashMap<String, String>();
    String pattern = format;
    String[] keyList = StringUtils.substringsBetween(format, "%{", "}");
    for (String str : keyList) {
        pattern = pattern.replaceAll("\\%\\{" + str + "\\}", ("(.+)"));
    }
    Pattern r = Pattern.compile(pattern);

    Matcher m = r.matcher(text);
    if(!m.find()) {
        throw new RuntimeException("regStr and originalString don't match");
    }
    for (int i = 0; i < m.groupCount(); i++) {
        map.put(keyList[i], m.group(i+1));
    }
    return map;
}
publicstaticvoidmain(字符串[]args){
//原始要求
println(getValueMap(“%{orgCity}到%{destCity}”,“德里到果阿”);
//具有两个单词值的变体
println(getValueMap(“%{orgCity}到%{destCity}”,“纽约到墨西哥”);
//另一种变体
println(getValueMap(“%{orgCity}到%{destCity}和更多”,“德里到果阿和更多”);
//语序不重要
println(getValueMap(“%{orgCity}%{destCity}to”,“德里果阿to”);
//与原始要求不同的字符串
println(getValueMap(“我要去%{firstCity}然后去%{secondCity}”,“我要去瑙鲁然后去西雅图”);
//两个以上的值,包含多个单词
println(getValueMap(“我是%{age}岁,我有%{eyescolor}只眼睛,%{pocketContent}在我的口袋里”,
“我今年20岁,有一双深蓝色的眼睛,口袋里有两枚硬币”);
//等等。。。
}
公共静态映射getValueMap(字符串格式,字符串文本){
Map Map=newhashmap();
字符串模式=格式;
String[]keyList=StringUtils.substringsBetween(格式,“%{”,“}”);
for(字符串str:keyList){
pattern=pattern.replaceAll(“\\%\\{”+str+“\\}”,(“(.+)”);
}
Pattern r=Pattern.compile(Pattern);
匹配器m=r.Matcher(文本);
如果(!m.find()){
抛出新的RuntimeException(“regStr和originalString不匹配”);
}
对于(int i=0;i
是时候练习你的正则表达式技能了


创建两个捕获组,并对每个字符串使用正则表达式。

如果捕获组的格式始终为:someCity to someCity,则可以使用
string.split
方法

String input = "delhi to goa";
String[] arr = input.split(" to ");
Map<String, String> map = new HashMap<>();
map.put(arr[0], arr[1]);
String input=“德里到果阿”;
字符串[]arr=input.split(“to”);
Map Map=newhashmap();
map.put(arr[0],arr[1]);
您可以使用regex
(\w+)\sto\s(\w+)
并可以找到两个组。 第1组为
,第2组为


你可以在

上测试这个正则表达式,我知道我不应该为你做你的工作,但是你提出的练习对我来说太有趣了,我无法抗拒:

此方法接收两个字符串并返回一个
Map
(好的,如果确实需要
HashMap
,只需更改返回类型即可):


格式可以不同。这就是问题所在。我需要使用给定的字符串创建正则表达式。谢谢morgano!!它真的帮了我。。。我自己也找到了解决这个问题的办法。我会把我写的代码贴在这里。
public static Map<String, String> getMap(String regStr, String originalString) {

    Pattern searchPattern = Pattern.compile("%\\{([^}]+)\\}");
    Matcher matcher = searchPattern.matcher(regStr);
    StringBuilder builder = new StringBuilder();
    List<String> keys = new LinkedList<>();
    Map<String, String> map = new HashMap<>();

    int start = 0;

    while(matcher.find()) {
        builder.append(Pattern.quote(regStr.substring(start, matcher.start())))
                .append("(.+)");
        start = matcher.end();
        keys.add(matcher.group(1));
    }
    builder.append(Pattern.quote(regStr.substring(start)));

    Pattern finalPattern = Pattern.compile(builder.toString());

    matcher = finalPattern.matcher(originalString);
    int pos = 0;
    if(!matcher.find()) {
        throw new RuntimeException("regStr and originalString don't match");
    }
    for(String key: keys) {
        map.put(key, matcher.group(++pos));
    }
    return map;
}
public static void main(String[] args) {

    // Original requirement
    System.out.println(getMap("%{orgCity} to %{destCity}", "delhi to goa"));

    // A variation with two words values
    System.out.println(getMap("%{orgCity} to %{destCity}", "New York to Mexico"));

    // Another variation
    System.out.println(getMap("%{orgCity} to %{destCity} and more", "delhi to goa and more"));

    // order of words doesn't matter
    System.out.println(getMap("%{orgCity} %{destCity} to", "delhi goa to"));

    // different strings than the original requirement
    System.out.println(getMap("I'm going to %{firstCity} and then to %{secondCity}", "I'm going to Nauru and then to Seattle"));

    // more than two values, with more than one word
    System.out.println(getMap("I am %{age} years old, I have %{eyesColour} eyes and %{pocketContent} in my pocket",
              "I am 20 years old, I have dark blue eyes and two coins in my pocket"));

    // etc ...
}