(如果我采取完全错误的指示让我知道是否有更好的方法我应该接近这个)
我有一个Java程序,它有多个模式,我想与输入进行比较。如果其中一个模式匹配,那么我想将该值保存在String中。我可以使用单一模式使用它,但我希望能够检查很多。
现在我要检查一个输入是否匹配一个模式:
Pattern pattern = Pattern.compile("TST\\w{1,}");
Matcher match = pattern.matcher(input);
String ID = match.find()?match.group():null;
所以,如果输入是TST1234或abcTST1234,那么ID =“TST1234”
我希望有多种模式,例如:
Pattern pattern = Pattern.compile("TST\\w{1,}");
Pattern pattern = Pattern.compile("TWT\\w{1,}");
...
然后到一个集合,然后根据输入检查每一个:
List<Pattern> rxs = new ArrayList<Pattern>();
rxs.add(pattern);
rxs.add(pattern2);
String ID = null;
for (Pattern rx : rxs) {
if (rx.matcher(requestEnt).matches()){
ID = //???
}
}
我不确定如何将ID设置为我想要的。我试过了
ID = rx.matcher(requestEnt).group();
和
ID = rx.matcher(requestEnt).find()?rx.matcher(requestEnt).group():null;
不确定如何完成这项工作或从哪里开始。任何帮助或建议表示赞赏。谢谢。
编辑:是的,模式会随着时间而改变。所以模板列表会增长。
我只需要获得匹配的字符串...即如果输入是abcTWT123,它将首先检查“TST \ w {1,}”,然后转到“TWT \ w {1,}”并且因为匹配ID ID将被设置为“TWT123”。
答案 0 :(得分:2)
要在结果中收集匹配的字符串,如果匹配的字符串少于整个字符串,则可能需要在regexp中创建一个组:
List<Pattern> patterns = new ArrayList<>();
patterns.add(Pattern.compile("(TST\\w+)");
...
Optional<String> result = Optional.empty();
for (Pattern pattern: patterns) {
Matcher matcher = pattern.match();
if (matcher.matches()) {
result = Optional.of(matcher.group(1));
break;
}
}
或者,如果您熟悉溪流:
Optional<String> result = patterns.stream()
.map(Pattern::match).filter(Matcher::matches)
.map(m -> m.group(1)).findFirst();
另一种方法是使用find
(如在@ Raffaele的回答中)隐式创建一个组。
您可能需要考虑的另一个选择是将所有匹配放在一个模式中。
Pattern pattern = Pattern.compile("(TST\\w+|TWT\\w+|...");
然后您可以在单个操作中进行匹配和分组。但是,随着时间的推移,这可能更难以改变比赛。
第1组是第一个匹配的组(即第一组括号内的匹配)。组0是整场比赛。所以,如果你想要整场比赛(我不确定你的问题)那么你也许可以使用0组。
答案 1 :(得分:1)
也许你只需要在第一个模式匹配时结束循环:
// TST\\w{1,}
// TWT\\w{1,}
private List<Pattern> patterns;
public String findIdOrNull(String input) {
for (Pattern p : patterns) {
Matcher m = p.matcher(input);
// First match. If the whole string must match use .matches()
if (m.find()) {
return m.group(0);
}
}
return null; // Or throw an Exception if this should never happen
}
答案 2 :(得分:1)
使用替换|
(正则表达式OR):
Pattern pattern = Pattern.compile("TST\\w+|TWT\\w+|etc");
然后只检查一次模式。
另请注意,{1,}
可以替换为+
。
答案 3 :(得分:0)
如果您的模式都是简单的前缀,例如 TST 和 TWT ,您可以一次定义所有这些,并且用户正则表达式替换{{1}所以你不需要遍历模式。
一个例子:
|
现在可以从java String prefixes = "TWT|TST|WHW";
String regex = "(" + prefixes + ")\\w+";
Pattern pattern = Pattern.compile(regex);
String input = "abcTST123";
Matcher match = pattern.matcher(input);
String ID = match.find() ? match.group() : null;
// given this, ID will come out as "TST123"
文件或简单的文本文件中读入prefixes
;或作为参数传递给执行此操作的方法
您还可以将前缀定义为逗号分隔列表或文件中的每行一个,然后在传递前将其转换为.properties
。
您可能正在循环几个输入,然后您只想创建one|two|three|etc
和regex
变量一次,只为每个单独的输入创建匹配器。