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