Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Java正则表达式从字符串解析此CSV列表?_Java_Regex - Fatal编程技术网

如何使用Java正则表达式从字符串解析此CSV列表?

如何使用Java正则表达式从字符串解析此CSV列表?,java,regex,Java,Regex,编辑:为了解释我这样做的动机,我正在编写一个命令行实用程序,它接受一个日志文件和一个模式(一个非正则表达式字符串,指示每个日志项的外观),将模式转换为正则表达式,并将文件的每一行与正则表达式匹配,生成一个日志事件集合,然后以另一种格式(如JSON)输出。我不能假设输入模式是什么或者文件包含什么 我想解析键值对的CSV列表。我需要从列表中捕获各个键和值。输入字符串示例: 2012年4月7日a=1,b=foo,c=bar:你好,世界\n 我希望下面的正则表达式正确地从输入中提取键和值: // re

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


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

2012年4月7日a=1,b=foo,c=bar:你好,世界\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"
group(1) == "a=1, b=foo, c=bar"
group(2) == "a"
group(3) == "1"
// no more matches
但是这个正则表达式(与上面的正则表达式相同,带有额外的“stuff”):

// 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! 
提取键和值的正确Java正则表达式是什么?

使用
“\\w+=\\w+”
获取结果:(“a=1”“b=foo”“c=bar”),使用
=
拆分正确的正则表达式取决于您试图实现的目标。在后一种情况下,关于正则表达式的结果是正确的。这是因为短语
是正则表达式的一部分,后面的
:.*
也是正则表达式的一部分,因此两者都将匹配,因此字符串中只有一个合适的片段

我个人会选择另一种解决方案,而不是直接使用regexp,我会使用
split
。例如,如果您感兴趣的部分始终介于
之间,并且该部分中没有此类字符,则您只需使用
子字符串
索引
拆分
。您可以进行两次拆分(一次使用
获取所有
键=值
对,然后在每对上执行
=
)。但这只是我的解决方案,可能不是最佳方案——我很乐意看到一个。

Regex:

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

几乎。它只适用于正好包含3个元素的CSV列表,但元素计数实际上可以是任何合理的正数。我非常感谢您的努力。:)起初,我认为这个程序解析解决方案(与纯正则表达式捕获组相比)限制太多,因为它假定模式中没有其他正则表达式(这是不正确的)。然而,对于这一点的所有答案都让我认为唯一可行的解决方案(至少目前是这样)是手动解析(以获取CSV列表),然后是列表本身的正则表达式匹配。
    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]