正则表达式匹配任何带引号的字符串或特定的未加引号的字符串

时间:2014-04-01 11:05:49

标签: regex csv

我需要使用正则表达式解析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”

1 个答案:

答案 0 :(得分:2)

更改正则表达式的这一部分:

(("[^"]*")|(NULL))

为:

("[^"]*"|NULL)

你那里有3个捕获组。首先包含("[^"]*")|(NULL),第二个包含"[^"]*",第三个包含NULL,如果您有NULL,则第一个捕获组中会有NULL,空第二个捕获组和第三个捕获组中的NULL

根据我的建议,您应该只有一个拥有"[^"]*"NULL的捕获组。