「ダメダ」はやっぱしダメだった…。
ここで言っている「回答者」は正しい。
本物の「バカ」完全互換じゃないのな…。検証用バッチ:
1 @echo %1
2 @echo %2
3 @echo %3
やってみる:
1 c:\do\me\s\to\s> aaa.bat "" aaa"bbb""" ccc
2 ""
3 aaa"bbb"""
4 ccc
CommandLineToArgvW は「正しいバカ」になりきれておらず、「バカの変種」を新たに生み出しただけ。
ちょっと回答者のコードが今のワタシの目的には過汎用なので単純化すると:
1 import re
2 def cmdline_split(s):
3 RE_CMD_LEX = r'''"((?:""|\\["\\]|[^"])*)"?()|(\\\\(?=\\*")|\\")|(&&?|\|\|?|\d?>|[<])|([^\s"&|<>]+)|(\s+)|(.)'''
4
5 args = []
6 accu = None # collects pieces of one arg
7 for qs, qss, esc, pipe, word, white, fail in re.findall(RE_CMD_LEX, s):
8 if word:
9 pass # most frequent
10 elif esc:
11 word = esc[1]
12 elif white or pipe:
13 if accu is not None:
14 args.append(accu)
15 if pipe:
16 args.append(pipe)
17 accu = None
18 continue
19 elif fail:
20 raise ValueError("invalid or incomplete shell string")
21 elif qs:
22 word = qs.replace('\\"', '"').replace('\\\\', '\\')
23 word = word.replace('""', '"')
24 else:
25 word = qss # may be even empty; must be last
26
27 accu = (accu or '') + word
28
29 if accu is not None:
30 args.append(accu)
31
32 return args
となるが、これだと確かに「バカ互換」になる。(無論「囲んでいる引用符まで垂れ流されてくる」のを剥がす差異は見かけ上出る。)
一つ前の記事で「DOS パーサに近しいご用を足せるもの」はこっちをベースに書こう…。