2012-07-30 115 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