2017-01-10 49 views
4

我有這樣提取參數

String pattern = "Send {{message}} to {{name}}"; 

字符串模式比我有這樣一個

String sentence = "Send Hi there to Jesus"; 

一句我想是與模式匹配句子和返回的東西像一個 JsonObject,它有以下句子的參數:

{"message": "Hi there", "name": "Jesus"} 

有沒有簡單的解決方案呢?

+3

如果你不熟悉正則表達式,然後有['MessageFormat.parse'(HTTPS: //docs.oracle.com/javase/8/docs/api/java/text/MessageFormat.html#parse(java.lang.String))。不過,我會使用[Regex](https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html)。 '發送\\ s +(?。*?)\\ s +到\\ s +(?。*)'應該這樣做。 –

+0

編輯問題標籤。設計模式標籤在這裏放錯了位置。請閱讀標籤的說明。 – CKing

+0

'MessageFormat.parse'是我想要的另一種方式。我不是很熟悉正則表達式,任何提示? –

回答

3

該單元測試通過引用匹配組(通過括號括起的圓括號)通過組索引來提取句子內容。如果模式匹配給定字符串,則整個輸入字符串爲組0.在給定示例中,匹配的message位於組索引1,name位於索引2.或者,您可以定義命名組。

@RunWith(Parameterized.class) 
public class Snippet { 

    private final String testSentence; 
    private final String[][] expectedResult; 



    public Snippet(String testSentence, String[][] expectedMessages) { 
     this.testSentence = testSentence; 
     this.expectedResult = expectedMessages; 
    } 

    private String[][] extractSentenceContent(String sentence) { 
     Pattern pattern = Pattern.compile("Send\\s([\\p{Alpha}\\s]+)\\sto\\s([\\p{Alpha}\\s]+)"); 
     Matcher matcher = pattern.matcher(sentence); 

     String[][] result; 

     if(matcher.matches()) { 
      result = new String[][] {{"message", matcher.group(1)}, {"name", matcher.group(2)}}; 
     } else { 
      result = null; 
     } 
     return result; 
    } 

    @Test 
    public void testRegex(){ 

     String[][] actualResult = extractSentenceContent(testSentence); 

     TestCase.assertTrue(Arrays.deepEquals(expectedResult, actualResult)); 
    } 



    @Parameters 
    public static Iterable<?> getTestParameters(){ 

     Object[][] parameters = { 
       {"Send Hi there to Jesus", new String[][] {{"message", "Hi there"}, {"name", "Jesus"}}} 
     }; 
     return Arrays.asList(parameters); 
    } 
} 

有沒有辦法從模板, 得到捕獲組名稱沒有硬編碼「消息」和「名」?

一個特設的解決辦法是使用String.format插入這樣的動態捕捉組名稱:

private String[][] extractSentenceContent(String sentence, String captureGroupA, String captureGroupB) { 
    String pattern = String.format("^Send\\s(?<%s>[\\p{Alpha}\\s]+)\\sto\\s(?<%s>[\\p{Alpha}\\s]+)$", captureGroupA, captureGroupB); 

    Matcher matcher = Pattern.compile(pattern).matcher(sentence); 

    String[][] result; 

    if(matcher.matches()) { 
     result = new String[][] { 
      {captureGroupA, matcher.group(captureGroupA)}, 
      {captureGroupB, matcher.group(captureGroupB)} 
     }; 
    } else { 
     result = null; 
    } 
    return result; 
} 
+1

您不需要兩個錨('^'和'$')和'matcher.matches'。 +1參數化單元測試 - 非常好的建議。 –

+0

有沒有辦法從模板中獲取捕獲組名稱,而不用硬編碼「消息」和「名稱」? –

+0

@ adi.neag這就是[我的例子(https://regex101.com/r/9ln6zr/2)一樣。我強烈建議不要盲目複製正則表達式,但無需理解 - 當需求發生變化時,它會回來咬你。 –

-1
i= sentence.length(); 

while(sentence[i] != " "){ 
    i--; 
} 

i++; 

for(intj=0;j<i;j++) 
    name[j]= sentence[j]; 
} 

for(int k = 5;k<(sentence.length()-i-3);k++){ 
    message[k] = sentence[k]; 
} 
+2

請格式化您發佈的代碼。請不要發佈代碼只有答案。 –

+1

最好在代碼中加入一些上下文/解釋,因爲這會使OP對未來的讀者更有用。 – EJoshuaS