2

编辑:为了解释我的动机,我正在编写一个命令行实用程序,它接受一个日志文件和一个模式(一个非正则表达式字符串,指示每个日志条目的样子),将模式转换为正则表达式,并匹配文件的每一行都带有正则表达式,生成一组日志事件,然后以另一种格式(例如 JSON)输出。我不能假设输入模式是什么或文件包含什么。


我想解析一个 CSV 键值对列表。我需要从列表中捕获各个键和值。示例输入字符串:

07/04/2012 <DEBUG> a=1, b=foo, c=bar : hello world!\n

验证了下面的正则表达式正确地从输入中提取键和值:

// regex
(([^,\s=]+)=([^,\s=]+)(?:,\s*(?:[^,\s=]+)=(?:[^,\s=]+))*?)

// input string
a=1, b=foo, c=bar

结果是:

// 1st call
group(1) == "a"
group(2) == "1"

// 2nd call
group(1) == "b"
group(2) == "foo"

// 3rd call
group(1) == "c"
group(2) == "bar"

但是这个正则表达式(与上面带有额外“东西”的正则表达式相同)不能按预期工作:

// regex
\d{2}/\d{2}/\d{4} <DEBUG> (([^,\s=]+)=([^,\s=]+)(?:,\s*(?:[^,\s=]+)=(?:[^,\s=]+))*?) : .*

// input string
07/04/2012 <DEBUG> a=1, b=foo, c=bar : hello world! 

由于某种原因,结果是:

group(1) == "a=1, b=foo, c=bar"
group(2) == "a"
group(3) == "1"
// no more matches

提取键和值的正确 Java 正则表达式是什么?

4

3 回答 3

1

正确的正则表达式取决于您要实现的目标。在后一种情况下,结果对于正则表达式是正确的。这是因为短语<DEBUG>是正则表达式的一部分,而结尾: .*也是正则表达式的一部分,因此两者都将被匹配,因此字符串中只有一个合适的片段。

我个人会寻求另一种解决方案 - 而不是直接使用正则表达式,我会使用split. 例如,如果您感兴趣的部分总是介于>和之间,: 并且substring该部分中没有这样的字符,您可以简单地与,indexOf和相处split。您可以进行两次拆分(一次,获得所有key=value对,然后=在每对上进行)。但这只是我的解决方案,它可能不是最佳解决方案 - 我很乐意看到一个。

于 2012-06-21T04:50:52.257 回答
1

使用"\\w+=\\w+"获取结果: ("a=1" "b=foo" "c=bar"),用 . 分割=

于 2012-06-21T04:44:42.337 回答
1

正则表达式:

\d{2}/\d{2}/\d{4}\s<DEBUG>\s([^=]+)=([^,\s]+)[,\s]([^=]+)=([^,\s]+)[,\s]([^=]+)=([^\s]+)\s:.*

编辑:如果计数可以是任意数字,请尝试以下一个。

    Scanner s = new Scanner("07/04/2012 <DEBUG> a=1, b=foo, c=bar : d=erere  m=abcd hello world!");
    Pattern p = Pattern.compile("(?<=\\s|,)[^\\s=]+=[^,\\s]+");
    String out;
    while((out = s.findInLine(p))!=null) {
        System.out.println(Arrays.toString(out.split("=")));
    }

输出:

[a, 1]
[b, foo]
[c, bar]
[d, erere]
[m, abcd]
于 2012-06-21T05:42:36.303 回答