Extract arguments from string pattern

490 views Asked by At

I have a String pattern like this

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

Than I have a sentence like this one

String sentence = "Send Hi there to Jesus";

What I want is to match sentences with a pattern and return something like a JsonObject that has the arguments from the sentence:

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

Are there any simple solutions for this ?

2

There are 2 answers

8
SME_Dev On BEST ANSWER

This unit test extracts the sentence content by refererencing matched groups (note the enclosing round brackets) via the group index. If the pattern matches the given string, then the entire input string is group 0. In the given example, the matched message is at group index 1 and the name at index 2. Alternatively, you can define named groups.

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

Is there any way to get the capturing group name from the template, without hardcoding "message" and "name" ?

An ad-hoc solution could be to use String.format to insert dynamic capture group names like this:

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;
}
2
Shlok Nangia On
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];
}