我正在尝试解析一个这样格式化的字符串,除了更多的值:
Key1=value,Key2=value,Key3=value,Key4=value,Key5=value,Key6=value,Key7=value
正则表达式
((Key1)=(.*)),((Key2)=(.*)),((Key3)=(.*)),((Key4)=(.*)),((Key5)=(.*)),((Key6)=(.*)),((Key7)=(.*))
在实际的字符串中,键值/值的数量大约是其两倍,但为了简洁起见,我将其缩短。我把它们括在括号中,所以我可以分组给它们打电话。我存储为常量的键,它们将始终相同。问题是,它永远不会找到一个没有意义的匹配(除非正则表达式是错误的)
答案 0 :(得分:8)
根据上面的评论判断,听起来你正在创建Pattern和Matcher对象并将Matcher与目标字符串相关联,但实际上你并没有应用正则表达式。这是一个非常常见的错误。这是完整的序列:
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
语句 - 也就是说,在调用任何需要Matcher处于“匹配”状态的group()
方法之前,应确保正则表达式实际上有效。
另请注意,大部分括号都没有。它们不是必需的,将它们排除可以更容易(1)阅读正则表达式和(2)跟踪组号。
答案 1 :(得分:2)
看起来你做得更好:
String[] pairs = data.split(",");
然后一次解析一个键/值对
答案 2 :(得分:1)
本身并没有错,但它需要大量的回溯,这可能会导致正则表达式引擎保释。我会按其他地方的建议尝试拆分,但如果你真的需要使用正则表达式,那么试着让它变得非贪婪。
((Key1)=(.*?)),((Key2)=(.*?)),((Key3)=(.*?)),((Key4)=(.*?)),((Key5)=(.*?)),((Key6)=(.*?)),((Key7)=(.*?))
要理解为什么需要这么多回溯,请理解
Key1=(.*),Key2=(.*)
适用于
Key1=x,Key2=y
Java的正则表达式引擎将第一个(.*)
与x,Key2=y
匹配,然后尝试从右侧剥离字符,直到它可以匹配正则表达式的其余部分:,Key2=(.*)
。它实际上最终会问,
""
是否与,Key2=(.*)
匹配,请尝试"y"
是否与,Key2=(.*)
匹配,请尝试"=y"
是否与,Key2=(.*)
匹配,请尝试"2=y"
是否与,Key2=(.*)
匹配,请尝试"y2=y"
是否与,Key2=(.*)
匹配,请尝试"ey2=y"
是否与,Key2=(.*)
匹配,请尝试"Key2=y"
是否与,Key2=(.*)
匹配,请尝试",Key2=y"
是否与,Key2=(.*)
匹配,是的,因此第一个.*
为"x"
,第二个为"y"
。编辑:
在Java中,非贪婪的限定符会改变一些事情,以便它开始尝试匹配任何东西,然后从那里构建。
"x,Key2=(.*)"
是否与,Key2=(.*)
匹配,请尝试",Key2=(.*)"
是否匹配,Key2=(.*)
,是。所以,当你有7个键时,它不需要匹配其中6个涉及不匹配5的5个涉及不匹配的4,......它可以通过输入在一个正向传递中完成它。
答案 3 :(得分:1)
你的正则表达式对我有用......
如果你总是遇到IllegalStateException,我会说你正在尝试做类似的事情:
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));
答案 4 :(得分:1)
我不会说没有正则表达式适用于此,但是写入(更重要的是,读取,对于下一个必须处理代码的人)而言,它很可能更复杂。我能用正则表达式得到的最接近的是你将一个终端逗号附加到你匹配的字符串上,而不是:
"Key1=value1,Key2=value2"
你会附加一个逗号,所以它是:
"Key1=value1,Key2=value2,"
然后,让我最接近的正则表达式是:"(?:(\\w+?)=(\\S+?),)?+"
...但是如果这些值有逗号的话,这不会很有效。
你可以尝试继续从那里调整那个正则表达式,但我发现的问题是贪婪和不情愿的量词之间的行为存在冲突。你必须指定一个贪婪值的捕获组,直到最后一个逗号,而非捕获组由单词字符后跟等号(下一个值)组成...最后一个非捕获组必须是可选的,以防你匹配序列中的最后一个值,并且可能本身不情愿。复杂。
相反,我的建议只是将字符串拆分为"="
。你可以放弃这个,因为大概不允许这些值包含等号字符。
现在你将拥有一堆子串,每个子串都是一串包含值的字符,字符串中的最后一个逗号,后跟一个键。您可以使用String.lastIndexOf(',')
轻松找到每个子字符串中的最后一个逗号。
特别处理第一个和最后一个子串(因为第一个没有前置值,最后一个没有附加键),你应该开始营业。
答案 5 :(得分:0)
如果你知道你总是有7,那么最低阻力是
^Key1=(.+),Key2=(.+),Key3=(.+),Key4=(.+),Key5=(.+),Key6=(.+),Key7=(.+)$
在http://www.fileformat.info/tool/regex.htm
处试试我很确定有一种更好的方法来解析这个事情,通过.find()而不是.matches(),我认为我会推荐它,因为它允许你向下移动字符串一键=价值对一次。它会让你进入整个“贪婪”的评估讨论。
答案 6 :(得分:0)
有些人在遇到问题时会想“我知道,我会用 正则表达式。“现在他们有两个问题。 - Jamie Zawinski
最简单的解决方案是最强大的。
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];
}