从字符串模式中提取参数

Extract arguments from string pattern

我有一个像这样的字符串模式

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

比我有这样一句话

String sentence = "Send Hi there to Jesus";

我想要的是用模式匹配句子 return 具有句子参数的 JsonObject:

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

有什么简单的解决方法吗?

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

此单元测试通过组索引引用匹配的组(注意封闭的圆括号)来提取句子内容。如果模式与给定的字符串匹配,则整个输入字符串是组 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);
    }
}

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

一个临时解决方案可能是使用 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;
}