代码之家  ›  专栏  ›  技术社区  ›  13ren

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

  •  2
  • 13ren  · 技术社区  · 16 年前

    我想在Java中使用多行字符串,所以我需要一个简单的预处理器,将C样式的多行转换成单字行。

    之前:

        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 backslash , newline 具有 转义文字反斜杠 , n . :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 \'\\\'");
    

    编辑 实际上,最好是使用perl/python风格的多行代码,在一行代码开始和结束(“”对于python,我认为是这样)。

    有没有更简单、更理智、更清晰的方法(可能不使用SED)?

    4 回复  |  直到 10 年前
        1
  •  3
  •   Adrian Pronk    16 年前

    一个Perl-One衬里:

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

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

    如果您使用的编辑器支持过滤,如vi或emacs,只需通过上面的命令过滤文本即可完成:

    如果你在用窗户,你得担心 \r 以下内容:

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

    尽管我认为win32 perl可以处理 R 所以这可能是不必要的。

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

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

        2
  •  5
  •   Community Mohan Dere    9 年前

    有没有更简单、更理智、更清晰的方法?

    忘记预处理器,忍受限制,抱怨它(以便它可能在Java 7或8中被固定),以及 use an IDE to ease the pain .

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

    • 使用支持此处文档的基于JVM的语言
    • 将字符串外部化为资源文件
        3
  •  1
  •   Lachlan Roche    16 年前

    一个Perl脚本来满足您的需求。

    while (<>) {
        chomp;
        print $_;
        if (/\\$/) {
            print "n";
        } else {
            print "\n";
        }
    }
    
        4
  •  0
  •   user4401178    10 年前
    sed 's/\x5c\x5c$/\x22\x5c\x5cn\x22/'
    

    反斜杠和双引号的十六进制分别是\x5c和\x22-它需要转义,因此\x5c是双倍的,$锚定在行尾。

    根据操作注释再次更新:

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

    :a创建一个标签,n将一行附加到图案空间,b a将分支回到标签:a,除非它的最后一行是$!(二)

    在它全部加载之后-一个单行替换用一个文本\n替换所有出现的换行符,使用十六进制ASCII代码\x5c作为反斜杠。