使用Java中的正则表达式将String解析为Map

时间:2018-01-05 12:52:50

标签: java regex text-parsing

我正在尝试解析这样的输入:

VAR1: 7, VAR2: [1,2,3], VAR3: value1=1,value2=2, TIMEZONE: GMT+5, TIME: 17:15:00

进入地图:

{VAR1=7, VAR2=[1,2,3], VAR3=value1=1,value2=2, TIMEZONE=GMT, TIME=17:15:00}

所以变量用逗号(,)分隔,它们的值在冒号(:)之后。它们并不总是大写,我这样写它们是为了让它更明显,哪些是变量的名称,哪些是值。此外,空格可以出现在名称或值的任何位置。 问题是逗号可以出现在VAR2或VAR3中的值中,冒号可以出现在TIME等变量中。

我尝试像这样拆分字符串以获取值:

final String regex = ",?\\s*(\\w+)\\s*:\\s*";
final String[] values = inputString.split(regex);

只要inputString不包含冒号值的任何时间变量,它就会起作用。否则,它将其返回为值:

[, 7, [1,2,3], value1=1,value2=2, GMT+5, , , 00]

而不是:

[7, [1,2,3], value1=1,value2=2, GMT+5, 17:15:00]

我怀疑它与TIME中的最后一个冒号相匹配,而不是位于变量名称之后的第一个冒号与它的值分开。 我尝试使用不情愿的量词来表示冒号“,?\ s *(\ w +)\ s *:?\ s ”但这又回复了:

[, :, , : [, , , ], :, =, , =, , :, +, , :, :, :]

这是胡说八道。 我很感激任何提高正则表达式的想法。

2 个答案:

答案 0 :(得分:0)

假设变量名不能以数字开头,日期/时间中的冒号不是问题。我对值中的逗号有更多问题。

以下是我解决问题的方法:

    String input = "VAR1: 7, VAR2: [1,2,3], VAR3: value1=1,value2=2, TIMEZONE: GMT+5, TIME: 17:15:00";
    Pattern re = Pattern.compile(
            "^\\s*(\\p{Alpha}\\p{Alnum}*)\\s*:\\s*(\\S*)(?:,\\s*(\\p{Alpha}\\p{Alnum}*\\s*:.*))?$");
    Matcher matcher = re.matcher(input);
    while (matcher.matches()) {
        String name = matcher.group(1);
        String value = matcher.group(2);
        String tail = matcher.group(3);
        System.out.println(name + ": " + value);
        if (tail == null) {
            break;
        }
        matcher = re.matcher(tail);
    }

结果:

VAR1: 7
VAR2: [1,2,3]
VAR3: value1=1,value2=2
TIMEZONE: GMT+5
TIME: 17:15:00

更新:

它也适用于:

    Pattern re = Pattern.compile(
            "^\\s*(\\w+)\\s*:\\s*(\\S*)(?:,\\s*(\\w+\\s*:.*))?\\s*$");

答案 1 :(得分:0)

可能的解决方案(online test):

import java.util.regex.Matcher;
import java.util.regex.Pattern;

final String regex = "(.+?):\\s?(.+?)(?:,\\W|$)";
final String string = "VAR1: 7, VAR2: [1,2,3], VAR3: value1 =1,value2=2, TIMEZONE: GMT+5, TIME: 17:15:00";

final Pattern pattern = Pattern.compile(regex);
final Matcher matcher = pattern.matcher(string);

while (matcher.find()) {
    System.out.println("Full match: " + matcher.group(0));
    for (int i = 1; i <= matcher.groupCount(); i++) {
        System.out.println("Group " + i + ": " + matcher.group(i));
    }
}

只需在地图中收集结果即可获得您要求的内容

正则表达式解释:

  • (.+?):捕获您的密钥(例如:VAR1
  • ::从字面上捕获:符号
  • \s?:捕获可选空间
  • (.+?):捕获您的值(例如:7
  • (?:,\\W|$):捕获逗号后跟空格(这两个符号一起是我们的实际分隔符)或字符串的结尾