1

如果我有一个逗号分隔的文件,如下所示:

富,酒吧,n
,A B C D
一二三
,A B C D

我想加入\n,制作这个:

foo,bar,n,a,bc,d
一、二、三、a、bc、d

什么是正则表达式技巧?我以为 anif (/\n,/)会抓住这个。

另外,我需要对 UTF-8 编码文件做任何特别的事情吗?

最后,Groovy 中的解决方案也会有所帮助。

4

5 回答 5

12

您应该使用Text::CSV_XS而不是自己这样做。它支持嵌入在记录中的换行符以及 Unicode 文件。创建解析器时需要指定正确的选项,因此请务必仔细阅读文档。

于 2008-11-10T18:26:38.397 回答
0

这对我有用:

open(F, "test.txt") or die;
undef $/;
$s = <F>;
close(F);
$s =~ s/\n,/,/g;
print $s;

$ cat test.txt
foo,bar,n
,a,bc,d
one,two,three
,a,bc,d
$ perl test.pl 
foo,bar,n,a,bc,d
one,two,three,a,bc,d
于 2008-11-10T18:27:21.423 回答
0

这是一个时髦的版本。根据要求,这可能无法捕捉到一些细微差别(例如可以在其中包含逗号的带引号的字符串)。如果换行符可以发生在字段的中间而不是总是在末尾,那么它也必须进行调整。

def input = """foo,bar,n
,a,bc,d
one,two,three
,a,bc,d"""

def answer = (input =~ /(.*\n?,){5}.*(\n|$)/).inject ("") { ans, match  ->
    ans << match.replaceAll("\n","") << "\n"
}

assert answer.toString() == 
"""foo,bar,n,a,bc,d
one,two,three,a,bc,d
"""
于 2008-11-11T05:26:30.327 回答
0

这可能太简单了(或者不能很好地处理一般情况),

def input = """foo,bar,n
,a,bc,d
one,two,three
,a,bc,d"""

def last
input.eachLine {
    if(it.startsWith(',')) {
        last += it;
        return;
    }
    if(last)
        println last;
    last = it
}
println last

发出;

foo,bar,n,a,bc,d
one,two,three,a,bc,d
于 2008-11-12T03:27:25.217 回答
0

这主要是为了回答您的 UTF-8 编码问题。

根据特定的编码,您可能还需要查找空字节。如果上述建议对您不起作用,将 's/\n,/,/g' 替换为 's/\c@?\n(\c@?,)/$1/g' 可能会在不破坏编码的情况下工作,尽管迭代地执行它可能更安全(将 's/\c@?\n(\c@?,)/$1/' 应用于每一行,而不是将它们连接起来并全局应用)。这确实是一个 hack,不能替代真正的 unicode 支持,但如果您只需要快速修复,或者如果您对编码有保证,它可能会有所帮助。

于 2008-11-12T23:04:11.470 回答