java - 从字符串中提取变量值

标签 java regex string

鉴于用户只能输入特定格式的值,我需要将该字符串的相关部分提取到 Java 变量中。

例如可接受的格式是:-

String types[] = {"The quick brown ${animal} jumped over the lazy ${target}.",
                  "${target} loves ${animal}.",
                  "${animal} became friends with ${target}"};

变量:-

private String animal;
private String target;

现在,如果用户输入“The Quick Brown Fox Jump over the Lazy Dog.”,则动物变量应设置为“fox”,目标变量应为设置为“狗”

如果用户输入与给定类型都不匹配,则应显示错误。

基本上我正在尝试做与org.apache.commons.lang.text.StrSubstitutor相反的事情。

我的方法(看起来效率低下,因此寻求帮助):-

创建正则表达式模式来找出输入字符串的类型,然后为每种类型编写不同的逻辑。例如,对于第一种类型,获取单词“brown”后面的单词并将其分配给变量animal,依此类推。

最佳答案

使用@Josh Withee的answer :-

/**
 * @param input         String from which values need to be extracted
 * @param templates     Valid regex patterns with capturing groups
 * @param variableNames Names for named capturing groups
 * @return Map with variableNames as the keys and the extracted strings as map values
 * OR an empty, non-null map if the input doesn't match with any template, or if there is no group with the given variableNames
 */
public static Map<String, String> extractVariablesFromString(String input, List<String> templates, String... variableNames) {
        Map<String, String> resultMap = new HashMap<>();
        Optional<String> matchedTemplate = templates.stream().filter(input::matches).findFirst();
        matchedTemplate.ifPresent(t -> {
            Matcher m = Pattern.compile(t).matcher(input);
            m.find();
            Arrays.stream(variableNames)
                    .forEach(v -> {
                        try {
                            resultMap.put(v, m.group(v));
                        } catch (IllegalArgumentException e) {
                        }
                    });
        });
        return resultMap;
    }

测试:-

    @Test
    public void shouldExtractVariablesFromString() {
        String input = "The quick brown fox jumped over the lazy dog.";
        String types[] = {"The quick brown (?<animal>.*) jumped over the lazy (?<target>.*).",
                "(?<target>.*) loves (?<animal>.*).",
                "(?<animal>.*) became friends with (?<target>.*)"};
        Map<String, String> resultMap = StringUtils.extractVariablesFromString(input, Arrays.asList(types), "animal", "target1", "target");
        Assert.assertEquals("fox", resultMap.get("animal"));
        Assert.assertEquals("dog", resultMap.get("target"));
        Assert.assertFalse(resultMap.containsKey("target1"));
    }

    @Test
    public void shouldReturnEmptyMapIfInputDoesntMatchAnyPatternForVariableExtraction() {
        String input = "The brown fox passed under the lazy dog.";
        String types[] = {"The quick brown (?<animal>.*) jumped over the lazy (?<target>.*).",
                "(?<animal>.*) became friends with (?<target>.*)"};
        Map<String, String> resultMap = StringUtils.extractVariablesFromString(input, Arrays.asList(types), "animal", "target1", "target");
        Assert.assertTrue(resultMap.isEmpty());
    }

关于java - 从字符串中提取变量值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49081955/

相关文章:

javascript - 我如何在 '\' 的字符串中替换所有 '/' 和 '-' 字符,在 javascript 中

java - 在Java中查找直到第n个单词的字符数?

java - 如何使用Spring AMQP读取队列中的消息?

java - 如何使用 HttpURLConnection 将序列化对象从 Java 类发送到 Servlet?

java - 在 JSP MVC 中加载 URL 时如何调用命令?

regex - 是否可以替换正则表达式序列中的特定字符?

javascript - 使用正则表达式删除常量后的所有内容

string - Racket 语言:如何将字符串转换为变量名

ios - 快速字符串操作

java - 如何在 Android 中制作一个没有新类的简单计时器?