用\ n替换尾部反斜杠\的最清楚的方法是什么?

时间:2010-02-09 06:04:04

标签: perl sed awk

我想在java中使用多行字符串,所以我寻求一个简单的预处理器,将C风格的多行转换为单行,文字为'\ n'。

在:

    System.out.println("convert trailing backslashes\
this is on another line\
\
\
above are two blank lines\
But don't convert non-trailing backslashes, like: \"\t\" and \'\\\'");

后:

     System.out.println("convert trailing backslashes\nthis is on another line\n\n\nabove are two blank lines\nBut don't convert non-trailing backslashes, like: \"\t\" and \'\\\'");

我认为sed会做得很好,但是sed是基于行的,所以替换'\'和它后面的换行符(有效加入两行)在sed中并不是很自然。我将sredden79's oneliner改编为以下内容 - 它有效,但它很聪明,但不清楚:

sed ':a { $!N; s/\\\n/\\n/; ta }'

替补是escaped literal backslashnewline escaped literal backslashn:a是标签,如果替代品找到匹配,则ta为goto标签; $表示最后一行,而$!则相反(即所有行,但最后一行)。 N表示将下一行附加到模式空间(从而使\n字符可见。)

编辑这里是保持编译器错误行号等准确的变体:它将每个扩展行转换为"..."+\n(并正确处理字符串的第一行和最后一行):

sed ':a { $!N; s/\\\n/\\n"+\n"/; ta }'

,并提供:

    System.out.println("convert trailing backslashes\n"+
"this is on another line\n"+
"\n"+
"\n"+
"above are two blank lines\n"+
"But don't convert non-trailing backslashes, like: \"\t\" and \'\\\'");

EDIT 实际上,最好使用Perl / Python风格的多行,它在一行上以特殊代码开头和结尾(对于python,我认为是“”)。 / p>

是否有更简单,更清晰,更清晰的方式(可能不使用sed)?

4 个答案:

答案 0 :(得分:5)

  

是否有更简单,更安全,更清晰的方式。

忘记预处理器,忍受限制,抱怨它(以便它可以在Java 7或8中修复)和use an IDE to ease the pain

其他替代方案(我认为太麻烦了,但仍然比搞乱编译过程更好):

  • 使用支持here-docs的基于JVM的语言
  • 将字符串外部化为资源文件

答案 1 :(得分:3)

perl one-liner:

perl -0777 -pe 's/\\\n/\\n/g'

这将读取stdin或在命令行上以它命名的文件,并将输出写入stdout。

如果你使用的是支持过滤的编辑器,比如vi或emacs,只需通过上面的命令过滤你的文字就可以了:

如果您使用的是Windows,则必须担心\r

C:\> perl -0777 -pe "s/\\\r?\n/\\n/g"

虽然我认为win32 Perl会处理\r本身,所以这可能是不必要的。

-0777选项是定义行或记录分隔符的-0(这是零)选项的特例。在这种情况下,这意味着我们不需要任何分隔符,因此将整个文件作为单个字符串读取。

-pe选项是-p(逐行处理并打印结果)和-e(下一个参数是要执行的程序的一行)的组合)

答案 2 :(得分:1)

你要求的perl脚本。

while (<>) {
    chomp;
    print $_;
    if (/\\$/) {
        print "n";
    } else {
        print "\n";
    }
}

答案 3 :(得分:0)

sed 's/\x5c\x5c$/\x22\x5c\x5cn\x22/'

反斜杠和双引号的十六进制分别是\ x5c和\ x22 - 它需要被转义,因此\ x5c加倍并且$ anchors到行的末尾。

根据OP评论再次更新:

sed "{:a;N;\$!b a};s/\x5c\x5c\n/\x5c\x5cn/g" 

:a创建一个标签,N在模式空间附加一条线,b a分支回标签:a除了最后一行$!

全部加载后 - 单行替换将替换所有出现的换行符\ n用文字&#39; \ n&#39;使用十六进制ascii代码\ x5c作为反斜杠。