Java 这个正则表达式不正确吗?没有找到匹配项
我试图通过如下格式的字符串进行解析,除了使用更多值:Java 这个正则表达式不正确吗?没有找到匹配项,java,regex,Java,Regex,我试图通过如下格式的字符串进行解析,除了使用更多值: Key1=value,Key2=value,Key3=value,Key4=value,Key5=value,Key6=value,Key7=value 正则表达式 ((键1)=(.*),((键2)=(.*),((键3)=(.*),((键4)=(.*),((键5)=(.*),((键6)=(.*),((键7)=(.*)) 在实际字符串中,键/值的数量大约是原来的两倍,但为了简洁起见,我将其保持简短。我把它们放在括号里,这样我就可以分组叫它们了。
Key1=value,Key2=value,Key3=value,Key4=value,Key5=value,Key6=value,Key7=value
正则表达式
((键1)=(.*),((键2)=(.*),((键3)=(.*),((键4)=(.*),((键5)=(.*),((键6)=(.*),((键7)=(.*))
在实际字符串中,键/值的数量大约是原来的两倍,但为了简洁起见,我将其保持简短。我把它们放在括号里,这样我就可以分组叫它们了。我存储的键是常量,它们永远都是一样的。问题是,它永远不会找到一个没有意义的匹配项(除非正则表达式是错误的)看起来您最好这样做:
String[] pairs = data.split(",");
然后一次解析一个键/值对如果你知道你总是有7个,那么阻力最小的方法就是
^Key1=(.+),Key2=(.+),Key3=(.+),Key4=(.+),Key5=(.+),Key6=(.+),Key7=(.+)$
试试看吧
我非常确定有一种更好的方法来解析这个东西,它是通过.find()而不是.matches(),我想我会推荐这种方法,因为它允许您一次将字符串向下移动一个key=value对。它将您带入整个“贪婪”评估讨论。它本身并没有错,但它需要大量回溯,这可能会导致正则表达式引擎退出。我会尝试其他地方建议的拆分,但如果您真的需要使用正则表达式,请尝试使其非贪婪
((Key1)=(.*?)),((Key2)=(.*?)),((Key3)=(.*?)),((Key4)=(.*?)),((Key5)=(.*?)),((Key6)=(.*?)),((Key7)=(.*?))
要理解为什么它需要如此多的回溯,首先要理解这一点
Key1=(.*),Key2=(.*)
适用于
Key1=x,Key2=y
Java的正则表达式引擎将第一个(.*)
匹配到x,Key2=y
,然后尝试从右侧剥离字符,直到它可以获得正则表达式其余部分的匹配:,Key2=(.*)
。它实际上是在问
”
是否匹配,键2=(.*)
,因此请尝试“y”
是否匹配,键2=(.*)
,因此请重试“=y”
是否匹配,键2=(.*)
,因此请重试“2=y”
是否匹配,键2=(.*)
,因此请重试“y2=y”
是否匹配,键2=(.*)
,因此请重试“ey2=y”
是否匹配,Key2=(.*)
,因此请重试“Key2=y”
是否匹配,Key2=(.*)
,因此请重试”,Key2=y“
是否匹配,Key2=(*)
,是,因此第一个*
是“x”
,第二个是“y”
“x,Key2=(.*)”
是否匹配,Key2=(.*)
,请不要尝试”,键2=(.*)”
匹配,键2=(.*)
,是所以当你有7个键时,不需要取消匹配其中的6个键,其中包括取消匹配的5个键,其中包括取消匹配的4个键。。。。它可以在一次向前传递输入的过程中完成它的工作。您的正则表达式正在为我工作 如果你总是得到一个非法的州例外,我想说你正在尝试做一些类似的事情:
matcher.group(1);
没有调用find()方法
在尝试获取组之前,需要调用该方法(否则调用group()方法将处于非法状态)
尝试一下:
String test = "Key1=value,Key2=value,Key3=value,Key4=value,Key5=value,Key6=value,Key7=value";
Pattern pattern = Pattern.compile("((Key1)=(.*)),((Key2)=(.*)),((Key3)=(.*)),((Key4)=(.*)),((Key5)=(.*)),((Key6)=(.*)),((Key7)=(.*))");
Matcher matcher = pattern.matcher(test);
matcher.find();
System.out.println(matcher.group(1));
根据上面的评论判断,听起来像是在创建模式和匹配器对象,并将匹配器与目标字符串相关联,但实际上并没有应用正则表达式。这是一个很常见的错误。以下是完整的顺序:
String regex = "Key1=(.*),Key2=(.*)"; // etc.
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(targetString);
// Now you have to apply the regex:
if (m.find())
{
String value1 = m.group(1);
String value2 = m.group(2);
// etc.
}
您不仅必须调用find()
或matches()
(或lookingAt()
,而且从来没有人使用过该函数),您应该始终在if
或while
语句中调用它——也就是说,在调用任何方法(如group()之前,您应该确保正则表达式实际工作
要求匹配器处于“匹配”状态
还请注意,大多数括号都没有。它们是不必要的,省略它们可以使(1)阅读正则表达式和(2)跟踪组号更容易
有些人在遇到问题时会想:“我知道,我会用
正则表达式。“现在他们有两个问题。”杰米·扎温斯基
最简单的解决方案是最稳健的
final String data = "Key1=value,Key2=value,Key3=value,Key4=value,Key5=value,Key6=value,Key7=value";
final String[] pairs = data.split(",");
for (final String pair: pairs)
{
final String[] keyValue = pair.split("=");
final String key = keyValue[0];
final String value = keyValue[1];
}
我不想说没有正则表达式可以解决这个问题,但它的编写(更重要的是,对于下一个需要处理代码的人来说)可能比它的价值更复杂。使用正则表达式,我能得到的最接近的结果是,如果在匹配的字符串中附加一个终端逗号,即,而不是:
"Key1=value1,Key2=value2"
您可以附加一个逗号,以便:
"Key1=value1,Key2=value2,"
然后,最接近我的正则表达式是:“(?:(\\w+?)=(\\S+?),)?+”
…但是如果这些值有逗号,这就不太管用了
你可以试着从那里继续调整正则表达式,但我发现的问题是贪婪的量词和不情愿的量词之间的行为存在冲突。您必须为值指定一个捕获组,该值相对于逗号贪婪,直到最后一个逗号,然后是由单词字符后跟等号(下一个值)组成的非捕获组。如果您匹配序列中的最后一个值,则最后一个非捕获组必须是可选的,也许它自己也不愿意。复杂
相反,我的建议是在“=”
上拆分字符串。您可以这样做,因为这些值可能不允许包含等号字符
现在您将有一组子字符串,每个子字符串都是一组字符,组成一个值,字符串中的最后一个逗号,后跟一个键。您可以使用String.lastIndexOf(',')
轻松找到每个子字符串中的最后一个逗号
特别处理第一个子字符串和最后一个子字符串(因为第一个子字符串没有预先指定的值,并且