我需要使用正则表达式解析CSV,并且一个特定列需要是引号中的字符串或NULL(作为字符串而不是空值)。
如果使用\,("[^"]*")
引用它,我可以获取该列,但是如果它是NULL,那么任何尝试获取它都会超出我的范围。我认为它类似于\,(("[^"]*")|(NULL))
,但这会导致奇怪的结果。
要解决问题,需要匹配:
“foo” 的
NULL
但不是:
巴
修改的
如果我使用值“这是一个字符串,包含它”,则匹配被拒绝(只接受("[^"]*")
)。接受NULL,但它不返回字符串'NULL',这不是我需要的行为)
这是完整的正则表达式:因为它出现在代码中:
@fields = $line =~ /^
(\d{0,10}+)
\,(\d{0,10}+)
\,([0-9\.]{0,6}+)
\,([0-9\.]{0,6}+)
\,([^,]*)
\,([^,]*)
\,(\d*\.?\d*)
\,(\d*\.?\d*)
\,([^,]*)
\,([^,]*)
\,([^,]*)
\,([^,]*)
\,([^,]*)
\,(\w{3}+)
\,(\w{3}+)
\,([^,]*)
\,([^,]*)
\,(\w{0,10})
\,(\d+)
\,([^,]*)
\,(\d{1}+)
\,(("[^"]*")|(NULL))
\,([^,]*)
\,([^,]*)
$
/xo;
这是一个示例行(对不起,如果它是荒谬的):
1111,111111,0,0,这是一些文字,1111.11,0.00,0.00,2014-03-14 11:11:1111.111,文字,2014-03-11 11:11:11.111,文字,文字, LLL,AAA,1900-01-01 00:00:00.000,1900-01-01 23:59:59.000,NULL,0,2014-03-11 11:00:11.111,1,NULL,1111111,NULL
输出:
1111
111111个
0
0
这是一些文字
1111.11
0.00
0.00
2014-03-14 11:11:1111.111
文字
2014-03-11 11:11:11.111
文字
文字
LLL
AAA
1900-01-01 00:00:00.000
1900-01-01 23:59:59.000
NULL
0
2014-03-11 11:00:11.111
1
NULL
NULL
1111111个
NULL
看起来它为\,((“[^”] *“)|(NULL))匹配返回3个值:NULL,一个空字符串,当它应该只返回一个NULL时为NULL。
如果我将重要的NULL(最后一个值中的第三个)括在引号中,我得到以下输出:
1111
111111个
0
0
这是一些文字
1111.11
0.00
0.00
2014-03-14 11:11:1111.111
文字
2014-03-11 11:11:11.111
文字
文字
LLL
AAA
1900-01-01 00:00:00.000
1900-01-01 23:59:59.000
NULL
0
2014-03-11 11:00:11.111
1
“NULL”
“NULL”
1111111
NULL
因此,它也输出3个值而不是输出的单个“NULL”
答案 0 :(得分:2)
更改正则表达式的这一部分:
(("[^"]*")|(NULL))
为:
("[^"]*"|NULL)
你那里有3个捕获组。首先包含("[^"]*")|(NULL)
,第二个包含"[^"]*"
,第三个包含NULL
,如果您有NULL
,则第一个捕获组中会有NULL
,空第二个捕获组和第三个捕获组中的NULL
。
根据我的建议,您应该只有一个拥有"[^"]*"
或NULL
的捕获组。