RegExp - 匹配可能的最短数量似乎不起作用

时间:2016-01-25 15:06:44

标签: regex linux

我想删除CSV文件中匹配双引号内的逗号。这里的关键是它必须在匹配的双引号之间。此RexExp似乎不起作用:

".*?,.*?"

如果引入问号,则找不到任何内容。所以以下内容不起作用:

s/\(".*?\),\(.*?"\)/\1;\2/g

以下行是输入测试行。它与最短的匹配不匹配。

21,C,101,1,,W,D,,"AAAAAAAA,, RBBBBBB,",CCCCCCCCCC DD EEEEEEEEEE,FFFFFF GGGGGGG HHHHHHHHH,III 101 JJ,,,,KKKKKKK LLLLLLLL M'MMMM N,"OOO, P'PPPP QQQQQQQQ RR R",SSSSSSSSSSSS TTTTTTTTTT,UUU 101 VV,,,,,12/1/1998,1/1/2050,ZZZZZZ

我想将“AAAAAAAA,RBBBBBB”,中的逗号更改为分号“AAAAAAAA ;; RBBBBBB;”“OOO,P 'PPPP QQQQQQQQQ RR R“”OOO; P'PPPP QQQQQQQQ RR R“,不改变输入行中的任何其他逗号。

3 个答案:

答案 0 :(得分:0)

FPAT的gnu-awk可以解决这个问题:

awk -v FPAT='"[^"]*"|[^,]*' -v OFS=, '{for(i=1; i<=NF; i++) gsub(/,/, ";", $i)} 1' file.csv

-v FPAT='"[^"]*"|[^,]*'将字段模式设置为"...",或者任何内容都不是逗号。一旦我们将单个字段很好地拆分为双引号或非逗号,我们只需迭代它们并使用gsub用分号替换逗号。

<强> Code Demo

<强>输出:

21,C,101,1,,W,D,,"AAAAAAAA RBBBBBB;",CCCCCCCCCC DD EEEEEEEEEE,FFFFFF GGGGGGG HHHHHHHHH,III 101 JJ,,,,KKKKKKK LLLLLLLL M'MMMM N,"OOO; P'PPPP QQQQQQQQ RR R",SSSSSSSSSSSS TTTTTTTTTT,UUU 101 VV,,,,,12/1/1998,1/1/2050,ZZZZZZ

答案 1 :(得分:0)

你的正则表达式有一个基本问题:.可以匹配任何字符,包括引号。懒惰的量词不能解决这个问题,它只是让它在简单的情况下起作用。

另外,如果有多个逗号

,您想要做什么?

请改为尝试:

"[^",]*?,[^",]*"

或者,在报价中处理多个逗号:

"([^",]*?,)+[^",]*"

请注意,这个正则表达式仍然可以匹配不需要的文本,如果你想要完全避免这一点,你必须使它更复杂,以匹配行起始锚和真正的引号对,而不是任何两个引号与逗号内。

答案 2 :(得分:0)

我已经对此进行了测试以处理您的示例输入:

s/\("[^"]*\),\([^"]*"\)/\1;\2/g

在OSX和linux上执行同样的结果:

$ echo 21,C,101,1,,W,D,,\"AAAAAAAA,, RBBBBBB,\",CCCCCCCCCC DD EEEEEEEEEE,FFFFFF GGGGGGG HHHHHHHHH,III 101 JJ,,,,KKKKKKK LLLLLLLL M\'MMMM N,\"OOO, P\'PPPP QQQQQQQQ RR R\",SSSSSSSSSSSS TTTTTTTTTT,UUU 101 VV,,,,,12/1/1998,1/1/2050,ZZZZZZ | sed -e 's/\("[^"]*\),\([^"]*"\)/\1;\2/g'
21,C,101,1,,W,D,,"AAAAAAAA,, RBBBBBB;",CCCCCCCCCC DD EEEEEEEEEE,FFFFFF GGGGGGG HHHHHHHHH,III 101 JJ,,,,KKKKKKK LLLLLLLL M'MMMM N,"OOO; P'PPPP QQQQQQQQ RR R",SSSSSSSSSSSS TTTTTTTTTT,UUU 101 VV,,,,,12/1/1998,1/1/2050,ZZZZZZ