2

我正在尝试将 javascript 代码移植到 Java。这样做,我需要用双引号字符串替换所有单引号字符串。这也需要我用转义的双引号替换双引号。但我只想转义单引号字符串块中的引号。

使用以下 sed 命令,我可以毫无问题地替换引用的字符串:

sed "s/'\([^']*\)'/\"\1\"/g"

这成功地将单引号字符串修改为双引号字符串。但我仍然必须逃避内部双引号。最简单的方法似乎是 sed 提供了一种方法来在一行的一部分上运行正则表达式替换。但我不知道这是否可能。

4

3 回答 3

1

我不认为你可以这样做,sed因为它的 POSIX 正则表达式引擎不知道环视。但是可以在(例如)Python 脚本中,通过将操作分为两个步骤:

import re
with open("myfile.js") as infile, open("myfile.jsconv", "w") as outfile:
    for line in infile:
    line = line.sub(
        r"""(?x)"  # Match a double quote
        (?=        # only if it's followed by:
         (?:       # an even number of quotes, defined like this:
          (?:      # Either...
           \\.     # any escaped character
          |        # or
           [^'\\]  # a character except single quotes
          )*       # repeated as needed, followed by
         '         # a single quote.
          (?:\\.|[^'\\])*  # (Repeat this to ensure an even
          '        # number of quotes)
         )*        # Do this zero or more times.
         (?:\\.|[^'\\])* # Then match any remaining characters
         $         # until the end of the line.
        )          # End of loohahead""", 
        '\\"', line)
    line = re.sub(
        r"""(?x)' # Match a single quote
        (         # Match and capture
         (?:      # either...
          \\.     # an escaped character
         |        # or
          [^'\\]  # a character besides quotes or backslashes
         )*       # any number of times.
        )         # End of capturing group number 1
        '         # Match a single quote""", 
        r'"\1"', line)
    outfile.write(line)
于 2012-07-30T06:08:03.887 回答
1

这可能对您有用(GNU sed):

sed '/'\''[^'\'']*'\''/!b;s//\n&\n/g;ba;:a;/\n\n/bb;s/\n['\'']/"\n/;ta;s/\n"/\\"\n/;ta;s/\n\([^'\''"]\+\)/\1\n/;ta;:b;s/\n\n//;ta' file

但是,如果引用的字符串可以是多行的,则需要稍微不同(但速度较慢)的方法:

sed ':a;$!{N;ba};/\x00/q1;s/'\''[^'\'']*'\''/\x00&\x00/g;bb;:b;/\x00\x00/bc;s/\x00['\'']/"\x00/;tb;s/\x00"/\\"\x00/;tb;s/\x00\([^'\''"]\+\)/\1\x00/;tb;:c;s/\x00\x00//;tb' file

这会将整个文件放入模式空间,然后\x00用作标记来分隔引用的字符串。它首先检查文件中是否\x00已经存在,如果存在则退出代码1,保持原始文件不变。

于 2012-07-30T07:22:58.113 回答
0

如果输入不是很复杂,这应该可以工作:

 sed ": loop s/\('[^']*[^\\]\)\"/\1\\\\\"/;t loop;s/'/\"/g" input_file
于 2012-07-31T10:00:23.570 回答