2012-07-30 117 views
2

我试图将JavaScript代码移植到Java。这样做,我需要用双引号字符串替换所有单引号字符串。这也要求我用双引号替换双引号。但我只想逃避单引号字符串块中的引号。sed正则表达式的部分行

我可以没有问题更换引用的字符串,使用下面的sed命令:

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

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

+0

您需要向前断言要做到这一点,和'sed'不支持的。为什么它必须是'sed'? – 2012-07-30 05:47:27

+0

难道在你正在处理的字符串中也会有单引号溢出吗? – 2012-07-30 05:51:57

回答

1

我不认为你可以用sed来做,因为它的POSIX正则表达式引擎不知道如何查找。

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) 
+0

...之前有人抱怨说我应该编译正则表达式:Python会自动执行并缓存它们:) – 2012-07-30 06:11:26

1

这可能会为你工作(GNU SED):但是,如果在(例如)一个Python脚本,由操作拆分成两个步骤可以

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,保持原始文件不变。

0

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

sed ": loop s/\('[^']*[^\\]\)\"/\1\\\\\"/;t loop;s/'/\"/g" input_file