使用正则表达式从字符串中提取键值对

时间:2014-06-04 09:24:35

标签: java regex

输入01:aa,bb,02:cc,03:dd,04:ee后,我需要提取以逗号分隔的键值对。值也可以包含逗号的问题。另一方面,索引的限制是它们只能是两位数字,键和值之间的分隔符总是冒号。

因此,上述输入的结果应该是以下正则表达式组:

01:aa,bb
02:cc, (comma is optional, can be stripped if exists)
03:dd, (comma is optional, can be stripped if exists)
04:ee

我尝试过使用(\d{2}:.+?,)*(\d{2}:.+?)$,但结果是:

0: 01:aa,bb,02:cc,03:dd,04:ee
1: 03:dd,
2: 04:ee

你有什么建议吗?

3 个答案:

答案 0 :(得分:3)

你可以使用前瞻和不情愿量词的组合。

例如:

String input = "01:aa,bb,02:cc,03:dd,04:ee";
//                           | group 1
//                           || group 2: 2 digits
//                           ||       | separator
//                           ||       | | group 3: any character reluctantly quantified...
//                           ||       | |  | ... followed by ...
//                           ||       | |  |  | ... comma and next digit as 
//                           ||       | |  |  | non-capturing group...
//                           ||       | |  |  |     | ... or...
//                           ||       | |  |  |     || ... end of input
//                           ||       | |  |  |     ||   | multiple matches in input
Pattern p = Pattern.compile("((\\d{2}):(.+?(?=(?:,\\d)|$)))+");
Matcher m = p.matcher(input);
while (m.find()) {
    System.out.println(m.group(2) + " --> " + m.group(3));
}

<强>输出

01 --> aa,bb
02 --> cc
03 --> dd
04 --> ee

注意

编辑为逗号后跟数字指定非捕获组 - 感谢Vld

答案 1 :(得分:2)

我认为这应涵盖所有情况:

Pattern regex = Pattern.compile("(\\d+):([\\w,]+)(?=,\\d|$)");

<强>解释

(\d+)    # Match and capture a number
:        # Match :
([\w,]+) # Match and capture an alphanumeric word (and/or commas)
(?=      # Make sure the match ends at a position where it's possible to match...
 ,\d     # either a comma, followed by a number
|        # or
 $       # the end of the string
)        # End of lookahead assertion

测试live on regex101.com

答案 2 :(得分:1)

Dario,这是一个非常简单的解决方案:用这个简单的正则表达式拆分字符串:

,(?=\d{2}:)

以下是代码:

String[] arrayOfPairs = subjectString.split(",(?=\\d{2}:)");

查看online demo底部的结果。

我建议这样做的原因是你似乎很乐意将一个键值对整体匹配,而不是将它们分成两个变量。

这是如何运作的?

我们分成一个逗号,,后跟两位数和一个冒号,由正向前瞻(?=\d{2}:)确定