鉴于用户只能输入特定格式的值,我需要将该字符串的相关部分提取到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 jumped over the lazy dog."
,则动物变量应设置为"fox"
,目标变量应设置为"dog"
。
如果用户输入与给定类型都不匹配,则应显示错误。
基本上我试图做org.apache.commons.lang.text.StrSubstitutor
所做的逆。
我的方法(看起来效率低下,因此请求帮助): -
创建正则表达式模式以找出输入字符串的类型,然后为每种类型编写不同的逻辑。例如,对于第一种类型,请获取单词“brown”之后的单词并将其分配给变量animal
,依此类推。
答案 0 :(得分:0)
您可以使用命名捕获组执行此操作:
String userInput = "dog loves fox.";
String types[] = {"The quick brown (?<animal>.*?) jumped over the lazy (?<target>.*?).",
"(?<target>.*?) loves (?<animal>.*?).",
"(?<animal>.*?) became friends with (?<target>.*?)"};
Matcher m;
for(int i=0; i<types.length(); i++;){
if(userInput.matches(types[i]){
m = Pattern.compile(types[i]).matcher(userInput);
break;
}
}
m.find();
String animal = m.group("animal");
String target = m.group("target");
答案 1 :(得分:0)
使用@ Marathon55的答案: -
/**
* @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());
}