2017-01-10 2 views
4

У меня есть образец Струнный как этотИзвлечение аргументов из строки шаблона

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

чем у меня есть предложение, как этот

String sentence = "Send Hi there to Jesus"; 

То, что я хочу, чтобы соответствовать предложения с рисунком и вернуть что-то как JSONObject, который имеет аргументы из предложения:

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

Есть ли простые решения для этого?

+3

Если вы не знакомы с Regex, то есть [ '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 + to \\ 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

Есть ли способ получить имя группы захвата из шаблона, без hardcoding «message» и «name»? –

+0

@ adi.neag вот что [мой пример] (https://regex101.com/r/9ln6zr/2). Я бы настоятельно рекомендовал против слепо копировать Regex без понимания, однако - он вернется, чтобы укусить вас, когда ваши требования меняются. –

-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

Смежные вопросы