2014-04-30 44 views
0

我的要求是,我有一個給定的字符串像 String originalString = "delhi to goa";字符串匹配找到在Java中的鍵值

而且我有一個字符串 String regStr = "%{orgCity} to %{destCity}";

給定的文本可以是任何格式。 (不僅是「德里飛往果阿」,也可以是「新德里果阿」)

現在,由於這兩個字符串,我想用鍵值對一個HashMap作爲

orgCity - >德令哈

DESTCITY - >果阿

這裏關鍵是%{和}內的字符串。值是originalString中的對應字符串。

這需要使用一些正則表達式/模式來實現。

我找不到解決方案。

有人可以幫忙嗎?

感謝

更新

解決方案:

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; 
} 

回答

2

這個正則表達式我知道我不應該爲你做你的工作,但你提出的運動真是太有趣了,我認爲我只是無法抗拒:

這個方法接收您的兩個字符串,並給你回Map(OK,只是改變返回類型,如果你真的想要一個HashMap代替):

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 ... 
} 
+0

謝謝摩根!它真的幫了我...我自己也找到了解決這個問題的辦法。將在這裏發佈我寫的代碼。 – pankaj

0

時間去練習你的正則表達式的技能http://www.regexr.com/

創建兩個拍攝組,正則表達式的每個字符串。

0

如果總是採用格式: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]); 
+0

格式可以不同。那就是問題所在。我需要使用給定的字符串創建正則表達式。 – pankaj

0

您可以使用正則表達式(\w+)\sto\s(\w+)並可以找到兩個組。 第1組爲key,第2組爲value

您可以測試http://rubular.com/