使用正则表达式解析字符串时的Java 8 lambda表达式回调类型
我想写一个函数,它可以根据正则表达式匹配字符串,并以所有组匹配项作为参数执行回调 我想到了这个,它是有效的:使用正则表达式解析字符串时的Java 8 lambda表达式回调类型,java,lambda,java-8,Java,Lambda,Java 8,我想写一个函数,它可以根据正则表达式匹配字符串,并以所有组匹配项作为参数执行回调 我想到了这个,它是有效的: private static void parse(String source, String regex, Consumer<String[]> callback) { //convert regex groups 1..n into integer array 0..n-1
private static void parse(String source, String regex,
Consumer<String[]> callback) {
//convert regex groups 1..n into integer array 0..n-1 and call
//consumer callback with this array
Matcher m = Pattern.compile(regex).matcher(source);
String[] ret = new String[m.groupCount()];
if (m.matches()) {
for (int i=0; i<m.groupCount(); i++) {
ret[i] = m.group(1+i);
}
callback.accept(ret);
}
}
私有静态void解析(字符串源、字符串正则表达式、,
消费者回调){
//将正则表达式组1..n转换为整数数组0..n-1并调用
//使用此数组的使用者回调
Matcher m=Pattern.compile(regex.Matcher)(源代码);
String[]ret=新字符串[m.groupCount()];
如果(m.matches()){
对于(int i=0;i处理数据(p[0],p[1]);
理想情况下,我希望能够做到这一点
parse(“add42,43”,“Add(\\d+?),(\\d+?)”,(x,y)->processData(x,y));
最优雅的方法是什么?我能想到的唯一方法是用1..n参数声明多个函数接口,并使用重写来处理它。有没有更好的主意,也许是反射?据我所知,问题是是否有一种语法糖用于数组的元组初始化,即:
val (hour, minutes, seconds) = new String[]{"12", "05", "44"};
…但它隐藏在lambda arguments声明中
据我所知,Java8中没有这样的语法,您的方法似乎是最方便的
Scala中也有类似的说明:
scala> val s = "Add 42,43"
scala> val r = "Add (\\d+?),(\\d+?)".r
scala> val r(x,y) = s
x: String = 42
y: String = 43
由于我现在已经自己解决了这个问题,所以我会在这里发布一个我提出的解决方案。如果有人提出更好的解决方案,可能是方法链接或更通用的解决方案,我会很乐意给出答案 您可以像这样使用下面的类:
Sring msg = "add:42,34";
ParseUtils.parse(msg, "add:(\\d+),(\\d+)", (int x,int y) -> simulator.add(x, y));
ParseUtils.parse(msg, "add:(\\d+),(\\d+)", simulator::add); //IntBiConsumer match
ParseUtils.parse(msg, "add:(.*?),", System.out::println);
下面是这个类(我省略了简单的错误处理和布尔返回,如果不匹配):
公共类ParseUtils{
@功能接口
公共接口使用者{void accept(字符串s);}
@功能接口
公共接口双消费者{void accept(字符串a,字符串b);}
//…您可以添加三角豆等。如果需要。。。
@FunctionInterface//方便地解析整数
公共接口IntBiConsumer{void accept(intx,inty);}
//实现-----
公共静态void解析(字符串src、字符串regex、使用者回调){
accept(parse(src,regex)[0]);
}
公共静态void解析(stringsrc、stringregex、BiConsumer回调){
String[]p=parse(src,regex);
callback.accept(p[0],p[1]);
}
公共静态void解析(字符串src、字符串regex、,
IntBiConsumer回调){
String[]p=parse(src,regex);
accept(Integer.parseInt(p[0]),Integer.parseInt(p[1]);
}
公共静态字符串[]解析(字符串源、字符串模式){
Pattern p=Pattern.compile(Pattern);
匹配器m=p.Matcher(源);
String[]ret=新字符串[m.groupCount()];
如果(m.matches()){
对于(int i=0;iI不完全确定您想要的是什么,但似乎varargs和lambda不能以您想要的方式混合使用。为了使用lambda,目标类型必须是函数接口,其单个方法有固定数量的参数,在编译时确定。问题的根源是直到运行时才知道有多少参数组在regexp中。如果只有一个组,如何调用processData
,因为它似乎需要两个参数?事实上,我认为,调用方知道regexp中有多少组,方法重写的想法可能会起作用。只是不使用单个方法。感谢Scala中的解决方案。我不知道这个技巧。我不会我想看看Java 8中是否还有其他解决方案。不是元组初始化,而是可能使用1、2或3个参数进行重写,然后使用数组进行更多操作。这将涵盖许多简单的解析情况。我想做重写是一种方法,我正要编写一些骨架代码,但有点懒。(我还想知道java的新型推理系统有多灵活)。
public class ParseUtils {
@FunctionalInterface
public interface Consumer { void accept(String s); }
@FunctionalInterface
public interface BiConsumer { void accept(String a, String b); }
//... you can add TriConsumer etc. if you need to ...
@FunctionalInterface //conveniently parses integers
public interface IntBiConsumer { void accept(int x, int y); }
// implementations -----
public static void parse(String src, String regex, Consumer callback) {
callback.accept(parse(src, regex)[0]);
}
public static void parse(String src, String regex, BiConsumer callback) {
String[] p = parse(src, regex);
callback.accept(p[0],p[1]);
}
public static void parse(String src, String regex,
IntBiConsumer callback) {
String[] p = parse(src, regex);
callback.accept(Integer.parseInt(p[0]), Integer.parseInt(p[1]));
}
public static String[] parse(String source, String pattern) {
Pattern p = Pattern.compile(pattern);
Matcher m = p.matcher(source);
String[] ret = new String[m.groupCount()];
if (m.matches()) {
for (int i=0; i<m.groupCount(); i++) {
ret[i] = m.group(1 + i);
}
}
return ret;
}
}