如何从Java中不断变化的模板中提取字符串?

时间:2019-03-06 20:24:37

标签: java regex string

我有一个关于考虑Java正则表达式/字符串操作的最佳实践的问题。

我有一个不断变化的String模板,让我们说这次看起来像这样:

 /get/{id}/person

我还有另一个与此模式匹配的字符串。

/get/1234ewq/person

请记住,图案可能随时更改,斜杠可能会消失等。

我想提取两者之间的差异,即处理结果为 1234ewq 。 我知道我可以逐个字符地遍历char并进行比较,但是,如果可能的话,我想找到一些使用正则表达式的聪明方法。

最好的Java方法是什么? 谢谢。

1 个答案:

答案 0 :(得分:2)

为了让您用正则表达式方法回答您的问题,我建立了一个小示例类,该类应提示您使用该类的方向(请参见下文)。

这种方法的问题是您动态创建一个依赖于模板字符串的正则表达式。这意味着您必须以某种方式验证模板不会干扰正则表达式的编译和匹配过程本身。 同样,如果您要在模板中多次使用相同占位符,则atm会导致生成的HashMap仅包含该类型的最后一个占位符映射的值。 通常,这是预期的行为,但这取决于您填充模板的策略。

一般来说,对于模板处理,您可以查看胡须库。 另外,正如Uli Sotschok所提到的,使用google-diff-match-patch之类的方法可能会更好。

public class StringExtractionFromTemplate {
    public static void main(String[] args) {
        String template =  "/get/{id}/person";
        String filledTemplate = "/get/1234ewq/person";

        System.out.println(diffTemplateInsertion(template, filledTemplate).get("id"));
    }


    private static HashMap<String, String> diffTemplateInsertion(String template, String filledTemplate){
        //language=RegExp
        String placeHolderPattern = "\\{(.+)}";

        HashMap<String, String> templateTranslation = new HashMap<>();

        String regexedTemplate = template.replaceAll(placeHolderPattern, "(.+)");
        Pattern pattern = Pattern.compile(regexedTemplate);

        Matcher templateMatcher = pattern.matcher(template);
        Matcher filledTemplateMatcher = pattern.matcher(filledTemplate);

        while (templateMatcher.find() && filledTemplateMatcher.find()) {
            if(templateMatcher.groupCount() == filledTemplateMatcher.groupCount()){
                for (int i = 1; i <= templateMatcher.groupCount(); i++) {
                    templateTranslation.put(
                            templateMatcher.group(i).replaceAll(placeHolderPattern,"$1"), 
                            filledTemplateMatcher.group(i)
                    );
                }
            }
        }

        return templateTranslation;
    }
}